booting portfolio.sys
0%
enter portfolio โ†’
SYSONLINE
UPTIME@WLINKโ€”
KTMโ€”
BSโ€”
SECTIONwhoami
BSโ€”
anik@wlink:~$
$whoami

Anik Shrestha

Assistant System Administrator ยท WorldLink Communication

locSwoyambhu, Kathmandu ยท mailanikshrestha84720@gmail.com

I keep production infrastructure up, quiet, and boring โ€” VoIP trunks, container clusters, log pipelines, and the reverse proxies in front of them.

anik@wlink: ~/about.txt

$ cat about.txt

# Objective

Looking for a challenging career with real scope to demonstrate what I can do โ€” I'm drawn to bigger outlooks, thriving on imagination and passion, and setting a standard that exceeds expectations.

A fun attitude at work is everything, and I'm a learner for life. Most days that means keeping VoIP trunks connected, containers healthy, and logs searchable โ€” quietly, before anyone notices something was wrong.

anik@wlink: ~/history

$ history --job -n 3

# Experience

Assistant System Administrator Jul 2025 โ€” now
Infotech Services Pvt. Ltd. โ€” outsourced to WorldLink Communication
  • Administer Linux servers (Ubuntu, CentOS) and Xen virtualization across production and staging
  • Run containerized workloads on Docker, orchestrated with Docker Swarm
  • Administer FreePBX/Asterisk VoIP: SIP trunk config, call routing, DID management
  • Configure and troubleshoot the Kannel SMS gateway
  • Administer the ELK Stack โ€” index lifecycle management, log pipeline design
  • Build and version-control syslog-ng log pipelines
  • Configure and maintain Nginx/Traefik reverse proxies
  • Run Redis for caching and Consul for service discovery
  • Set up Prometheus + Grafana monitoring with custom dashboards
Enterprise Support / Monitoring May 2022 โ€” Jul 2024
Infotech Services Pvt. Ltd. โ€” outsourced to WorldLink Communication
  • Opened, tracked, and closed incident tickets; monitored customer circuits
  • Troubleshot customer-reported issues remotely
  • Monitored routers, switches, OLTs, and servers
  • Configured switches, routers, firewalls, and OLTs
ITSR / CSR Nov 2021 โ€” May 2022
Kalash Services โ€” BPO of WorldLink Communication
  • Handled inbound calls and logged customer issues
  • First-line troubleshooting of network and client-end devices
  • Troubleshot IPTV connections and configured customer devices
anik@wlink: ~/skills

$ ls -la ~/skills/ โ€” click any to inspect

# Skills

Systems & Virtualization

Containers & Orchestration

Telephony & Messaging

Observability & Logging

Networking & Service Infra

Network Ops

anik@wlink: ~/docs

$ cat docs/*.md โ€” full install & config notes

# Documentation

Complete step-by-step installation and working configuration examples for the production stack I run daily.

Docker & Docker Swarm

1. Install Docker Engine

# Download and run the official install script
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

# Add your user to the docker group (so you don't need sudo)
sudo usermod -aG docker $USER
# Log out and log back in, or run:
newgrp docker

# Start and enable Docker
sudo systemctl enable --now docker

# Verify installation
docker version
docker run --rm hello-world

2. Initialize Docker Swarm (on manager node)

# Replace 10.10.10.1 with the IP other nodes can reach
docker swarm init --advertise-addr 10.10.10.1

# Get the worker join command
docker swarm join-token worker

# On every worker node run the join command, for example:
docker swarm join --token SWMTKN-1-xxxxx 10.10.10.1:2377

# Check cluster status
docker node ls
docker info | grep -A 10 Swarm

3. Example production stack (docker-compose.yml)

version: "3.8"

services:
  web:
    image: nginx:1.25-alpine
    ports:
      - target: 80
        published: 80
        protocol: tcp
        mode: ingress
    volumes:
      - web_data:/usr/share/nginx/html:ro
    deploy:
      mode: replicated
      replicas: 3
      update_config:
        parallelism: 1
        delay: 10s
        failure_action: rollback
        order: start-first
      rollback_config:
        parallelism: 1
        delay: 5s
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
      resources:
        limits:
          cpus: "0.50"
          memory: 128M
        reservations:
          cpus: "0.25"
          memory: 64M
    networks:
      - frontend
    healthcheck:
      test: ["CMD", "wget", "-q", "--spider", "http://localhost/"]
      interval: 15s
      timeout: 5s
      retries: 3

  redis:
    image: redis:7-alpine
    command: >
      redis-server
      --requirepass StrongRedisPass123
      --maxmemory 256mb
      --maxmemory-policy allkeys-lru
    deploy:
      replicas: 1
      placement:
        constraints:
          - node.role == manager
      restart_policy:
        condition: on-failure
    networks:
      - backend
    volumes:
      - redis_data:/data

networks:
  frontend:
    driver: overlay
  backend:
    driver: overlay

volumes:
  web_data:
  redis_data:

4. Deploy and manage the stack

# Deploy
docker stack deploy -c docker-compose.yml prod

# List services
docker service ls

# Inspect a service
docker service ps prod_web
docker service logs -f prod_web

# Scale
docker service scale prod_web=5

# Update image with rolling update
docker service update --image nginx:1.26-alpine prod_web

# Remove stack
docker stack rm prod
Kannel SMS Gateway

1. Install Kannel

# Debian / Ubuntu packages
sudo apt update
sudo apt install -y kannel

# Create log directory if missing
sudo mkdir -p /var/log/kannel
sudo chown kannel:kannel /var/log/kannel

# Enable and start
sudo systemctl enable kannel
sudo systemctl start kannel
sudo systemctl status kannel

2. Full working kannel.conf (/etc/kannel/kannel.conf)

group = core
admin-port = 13000
smsbox-port = 13001
admin-password = StrongAdminPass
status-password = StatusPass123
admin-deny-ip = "*.*.*.*"
admin-allow-ip = "127.0.0.1;10.*.*.*"
log-file = /var/log/kannel/bearerbox.log
log-level = 0
box-deny-ip = "*.*.*.*"
box-allow-ip = "127.0.0.1"
access-log = /var/log/kannel/access.log

# SMSC connection (SMPP example)
group = smsc
smsc = smpp
smsc-id = provider1
host = smpp.provider.com
port = 2775
smsc-username = your_smpp_user
smsc-password = your_smpp_pass
system-type = 
address-range = 
transceiver-mode = true
enquire-link-interval = 30
reconnect-delay = 10
source-addr-ton = 1
source-addr-npi = 1
dest-addr-ton = 1
dest-addr-npi = 1

# SMSBox
group = smsbox
bearerbox-host = 127.0.0.1
bearerbox-port = 13001
sendsms-port = 13013
sendsms-chars = "0123456789 +-"
log-file = /var/log/kannel/smsbox.log
log-level = 0
access-log = /var/log/kannel/smsbox-access.log
mo-recode = true

# sendsms-user (HTTP API)
group = sendsms-user
username = smsuser
password = SmsApiPass123
user-deny-ip = "*.*.*.*"
user-allow-ip = "127.0.0.1;10.*.*.*"
max-messages = 10
concatenation = true

# Default SMS service (optional DLR)
group = sms-service
keyword = default
text = "Message received"
max-messages = 0
accept-x-kannel-headers = true

3. Restart and test

# Restart after config change
sudo systemctl restart kannel

# Check status via admin interface
curl "http://127.0.0.1:13000/status?password=StatusPass123"

# Send a test SMS via HTTP API
curl "http://127.0.0.1:13013/cgi-bin/sendsms?\
username=smsuser&\
password=SmsApiPass123&\
to=97798XXXXXXXX&\
from=SenderID&\
text=Hello%20from%20Kannel"

# Watch logs
sudo tail -f /var/log/kannel/bearerbox.log
sudo tail -f /var/log/kannel/smsbox.log
ELK Stack (Elasticsearch + Logstash + Kibana)

1. Add Elastic repository and install

# Import GPG key
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo gpg --dearmor -o /usr/share/keyrings/elasticsearch-keyring.gpg

# Add repo (Debian/Ubuntu example)
echo "deb [signed-by=/usr/share/keyrings/elasticsearch-keyring.gpg] https://artifacts.elastic.co/packages/8.x/apt stable main" | \
  sudo tee /etc/apt/sources.list.d/elastic-8.x.list

sudo apt update
sudo apt install -y elasticsearch logstash kibana

# Enable services
sudo systemctl enable elasticsearch logstash kibana

2. Elasticsearch config (/etc/elasticsearch/elasticsearch.yml)

cluster.name: wlink-logs
node.name: node-1
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
network.host: 0.0.0.0
http.port: 9200
discovery.type: single-node

# For production later: enable security
xpack.security.enabled: false
xpack.security.http.ssl.enabled: false

3. Start Elasticsearch and verify

sudo systemctl start elasticsearch
# Wait ~20-30 seconds then:
curl -X GET "http://localhost:9200/"
curl -X GET "http://localhost:9200/_cluster/health?pretty"

4. Logstash pipeline example (/etc/logstash/conf.d/beats.conf)

input {
  beats {
    port => 5044
  }
}

filter {
  if [fields][log_type] == "nginx" {
    grok {
      match => { "message" => "%{COMBINEDAPACHELOG}" }
    }
    date {
      match => [ "timestamp", "dd/MMM/yyyy:HH:mm:ss Z" ]
    }
  }

  if [fields][log_type] == "syslog" {
    grok {
      match => { "message" => "%{SYSLOGTIMESTAMP:timestamp} %{SYSLOGHOST:host} %{DATA:program}(?:\[%{POSINT:pid}\])?: %{GREEDYDATA:syslog_message}" }
    }
  }
}

output {
  elasticsearch {
    hosts => ["http://localhost:9200"]
    index => "logs-%{[fields][log_type]}-%{+YYYY.MM.dd}"
  }
  # Uncomment for debugging
  # stdout { codec => rubydebug }
}

5. Kibana config (/etc/kibana/kibana.yml)

server.port: 5601
server.host: "0.0.0.0"
elasticsearch.hosts: ["http://localhost:9200"]
logging.appenders.file.type: file
logging.appenders.file.fileName: /var/log/kibana/kibana.log
logging.appenders.file.layout.type: json

6. Start remaining services

sudo systemctl start logstash
sudo systemctl start kibana

# Check
sudo systemctl status elasticsearch logstash kibana
curl http://localhost:5601/api/status
Nginx

1. Install

sudo apt update
sudo apt install -y nginx
sudo systemctl enable --now nginx
nginx -v

2. Reverse-proxy site config (/etc/nginx/sites-available/app.example.com)

upstream backend_app {
    least_conn;
    server 127.0.0.1:8080 max_fails=3 fail_timeout=30s;
    server 127.0.0.1:8081 max_fails=3 fail_timeout=30s;
    keepalive 32;
}

server {
    listen 80;
    listen [::]:80;
    server_name app.example.com;

    # Redirect to HTTPS
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name app.example.com;

    ssl_certificate     /etc/letsencrypt/live/app.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/app.example.com/privkey.pem;
    ssl_protocols       TLSv1.2 TLSv1.3;
    ssl_ciphers         HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;
    ssl_session_cache   shared:SSL:10m;
    ssl_session_timeout 10m;

    access_log /var/log/nginx/app.access.log;
    error_log  /var/log/nginx/app.error.log;

    client_max_body_size 20M;

    location / {
        proxy_pass http://backend_app;
        proxy_http_version 1.1;
        proxy_set_header Host              $host;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Connection        "";
        proxy_connect_timeout 60s;
        proxy_send_timeout    60s;
        proxy_read_timeout    60s;
    }

    location /health {
        access_log off;
        return 200 "ok\n";
        add_header Content-Type text/plain;
    }
}

3. Enable site and test

sudo ln -s /etc/nginx/sites-available/app.example.com /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

# Optional: certbot for Let's Encrypt
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d app.example.com
Traefik

1. Run Traefik with Docker (common pattern)

# Create network
docker network create traefik-public

# traefik.yml (static config)
# Save as /opt/traefik/traefik.yml
api:
  dashboard: true
  insecure: false

entryPoints:
  web:
    address: ":80"
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https
  websecure:
    address: ":443"

providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false
    network: traefik-public
  file:
    directory: /etc/traefik/dynamic
    watch: true

certificatesResolvers:
  letsencrypt:
    acme:
      email: admin@example.com
      storage: /letsencrypt/acme.json
      httpChallenge:
        entryPoint: web

log:
  level: INFO

2. Docker run / stack service for Traefik

docker run -d \
  --name traefik \
  --restart unless-stopped \
  -p 80:80 -p 443:443 \
  -v /var/run/docker.sock:/var/run/docker.sock:ro \
  -v /opt/traefik/traefik.yml:/etc/traefik/traefik.yml:ro \
  -v /opt/traefik/letsencrypt:/letsencrypt \
  -v /opt/traefik/dynamic:/etc/traefik/dynamic \
  --network traefik-public \
  traefik:v3.0

3. Example service labels (in docker-compose)

services:
  myapp:
    image: myapp:latest
    networks:
      - traefik-public
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.myapp.rule=Host(`app.example.com`)"
      - "traefik.http.routers.myapp.entrypoints=websecure"
      - "traefik.http.routers.myapp.tls.certresolver=letsencrypt"
      - "traefik.http.services.myapp.loadbalancer.server.port=8080"
      - "traefik.docker.network=traefik-public"
Redis

1. Install

sudo apt update
sudo apt install -y redis-server
sudo systemctl enable redis-server

2. Production-oriented redis.conf edits (/etc/redis/redis.conf)

# Bind only to localhost (or private IP)
bind 127.0.0.1

# Require password
requirepass StrongRedisPassHere123

# Persistence
appendonly yes
appendfsync everysec

# Memory management
maxmemory 512mb
maxmemory-policy allkeys-lru

# Security / performance
protected-mode yes
tcp-backlog 511
timeout 0
tcp-keepalive 300

# Logging
loglevel notice
logfile /var/log/redis/redis-server.log

# supervised by systemd
supervised systemd

3. Apply and test

sudo systemctl restart redis-server
sudo systemctl status redis-server

# Test auth
redis-cli
> AUTH StrongRedisPassHere123
> PING
PONG
> SET test "hello"
> GET test
> INFO memory

4. Example systemd override (optional)

# /etc/systemd/system/redis-server.service.d/override.conf
[Service]
LimitNOFILE=65535

sudo systemctl daemon-reload
sudo systemctl restart redis-server
Consul

1. Install binary

# Download latest from HashiCorp
VER=1.20.0
curl -fsSL https://releases.hashicorp.com/consul/${VER}/consul_${VER}_linux_amd64.zip -o consul.zip
sudo apt install -y unzip
unzip consul.zip
sudo mv consul /usr/local/bin/
consul version

# Create user and directories
sudo useradd --system --home /etc/consul.d --shell /bin/false consul
sudo mkdir -p /etc/consul.d /var/lib/consul
sudo chown -R consul:consul /etc/consul.d /var/lib/consul

2. Server config (/etc/consul.d/server.hcl)

server = true
bootstrap_expect = 1
data_dir = "/var/lib/consul"
client_addr = "0.0.0.0"
bind_addr = "10.10.10.1"          # this node's IP
advertise_addr = "10.10.10.1"
ui_config {
  enabled = true
}
connect {
  enabled = true
}
ports {
  grpc = 8502
}
log_level = "INFO"
enable_syslog = true

3. Systemd unit (/etc/systemd/system/consul.service)

[Unit]
Description=HashiCorp Consul
Requires=network-online.target
After=network-online.target

[Service]
User=consul
Group=consul
ExecStart=/usr/local/bin/consul agent -config-dir=/etc/consul.d
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

4. Start and register a service

sudo systemctl enable --now consul
consul members

# Register a service via HTTP API
curl -X PUT -d '{
  "Name": "web",
  "ID": "web-1",
  "Address": "10.10.10.5",
  "Port": 80,
  "Check": {
    "HTTP": "http://10.10.10.5/health",
    "Interval": "10s",
    "Timeout": "2s"
  }
}' http://127.0.0.1:8500/v1/agent/service/register

# Query
curl http://127.0.0.1:8500/v1/catalog/services
curl http://127.0.0.1:8500/v1/health/service/web?pass
Prometheus + Grafana

1. Install Prometheus

VER=2.54.1
curl -fsSL https://github.com/prometheus/prometheus/releases/download/v${VER}/prometheus-${VER}.linux-amd64.tar.gz -o prometheus.tar.gz
tar xzf prometheus.tar.gz
cd prometheus-${VER}.linux-amd64

sudo useradd --system --no-create-home --shell /bin/false prometheus
sudo mkdir -p /etc/prometheus /var/lib/prometheus
sudo cp prometheus promtool /usr/local/bin/
sudo cp -r consoles console_libraries /etc/prometheus/
sudo chown -R prometheus:prometheus /etc/prometheus /var/lib/prometheus

2. Prometheus config (/etc/prometheus/prometheus.yml)

global:
  scrape_interval: 15s
  evaluation_interval: 15s

alerting:
  alertmanagers:
    - static_configs:
        - targets: []

rule_files: []

scrape_configs:
  - job_name: "prometheus"
    static_configs:
      - targets: ["localhost:9090"]

  - job_name: "node"
    static_configs:
      - targets: ["localhost:9100"]

  - job_name: "docker"
    static_configs:
      - targets: ["localhost:9323"]

  - job_name: "nginx"
    static_configs:
      - targets: ["localhost:9113"]

3. Prometheus systemd unit

# /etc/systemd/system/prometheus.service
[Unit]
Description=Prometheus
Wants=network-online.target
After=network-online.target

[Service]
User=prometheus
Group=prometheus
Type=simple
ExecStart=/usr/local/bin/prometheus \
  --config.file=/etc/prometheus/prometheus.yml \
  --storage.tsdb.path=/var/lib/prometheus \
  --web.console.templates=/etc/prometheus/consoles \
  --web.console.libraries=/etc/prometheus/console_libraries \
  --web.listen-address=0.0.0.0:9090
Restart=on-failure

[Install]
WantedBy=multi-user.target

# Then:
sudo systemctl daemon-reload
sudo systemctl enable --now prometheus

4. Node Exporter (host metrics)

VER=1.8.2
curl -fsSL https://github.com/prometheus/node_exporter/releases/download/v${VER}/node_exporter-${VER}.linux-amd64.tar.gz | tar xz
sudo cp node_exporter-${VER}.linux-amd64/node_exporter /usr/local/bin/
sudo useradd -rs /bin/false node_exporter

# Simple systemd unit
cat <

          

5. Install Grafana

# Official apt repo
sudo apt install -y apt-transport-https software-properties-common
wget -q -O - https://packages.grafana.com/gpg.key | sudo gpg --dearmor -o /usr/share/keyrings/grafana.gpg
echo "deb [signed-by=/usr/share/keyrings/grafana.gpg] https://packages.grafana.com/oss/deb stable main" | \
  sudo tee /etc/apt/sources.list.d/grafana.list

sudo apt update
sudo apt install -y grafana
sudo systemctl enable --now grafana-server

# Default login: admin / admin  โ†’ change immediately
# UI: http://YOUR_IP:3000

6. Add Prometheus data source in Grafana

# Via UI: Configuration โ†’ Data sources โ†’ Add โ†’ Prometheus
# URL: http://localhost:9090
# Or via provisioning file /etc/grafana/provisioning/datasources/prometheus.yml:

apiVersion: 1
datasources:
  - name: Prometheus
    type: prometheus
    access: proxy
    url: http://localhost:9090
    isDefault: true
    editable: false
anik@wlink: ~/contact

$ cat contact.txt

# Contact

Based in
Swoyambhu, Kathmandu
Permanent address
Pathlaiya, Bara
anik@wlink: ~
anik@wlink:~$