Listing posts

Displaying posts 6 - 10 of 189 in total
NetworkManager WiFi Power Saving
mouse 8 · person cloud · link
Last update
2019-03-09
2019
03-09
« — »
1
2
3
4
# /etc/NetworkManager/conf.d/wifi-powersave.conf 
[connection]
# 0=use default, 1=ignore/don't touch, 2=disable, 3=enable
wifi.powersave = 2

Source: gist.github.com/jcberthon


~~~ * ~~~

DNSmasq Authoritative config
mouse 7 · person cloud · link
Last update
2019-03-07
2019
03-07
« — »
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# ----------------------------------------------------------------------------
# Authoritative DNS config for yourdomain.tld
# Example for replacing Bind with dnsmasq
# Source: Stefan Onderka, http://www.onderka.com
# Description: https://www.onderka.com/inhalt/autoritativer-dns-server-mit-dnsmasq/
# Revision 2016-02-10
# ----------------------------------------------------------------------------
# https://www.onderka.com/inhalt/eigener-dyndns-mit-dnsmasq-apache-und-php/
# https://www.onderka.com/inhalt/eigener-dyndns-mit-bind-apache-und-php/
# http://www.thekelleys.org.uk/dnsmasq/docs/dnsmasq-man.html
# http://www.thekelleys.org.uk/dnsmasq/doc.html
# http://www.thekelleys.org.uk/dnsmasq/docs/FAQ
# http://comments.gmane.org/gmane.network.dns.dnsmasq.general/7621
# https://wiki.archlinux.org/index.php/dnsmasq
# ----------------------------------------------------------------------------
# Hostname:     yourdomain.tld
# IPv4 address: 10.20.30.40
# IPv6 address: ip:v6::ad::dr:ess
# ----------------------------------------------------------------------------

# Basics
# ----------------------------------------------------------------------------
listen-address=127.0.0.1
listen-address=10.20.30.40
listen-address=ip:v6::ad::dr:ess
no-dhcp-interface=eth0
# Port
port=53
bind-interfaces
#bogus-priv
#domain-needed
# User and group
user=dnsmasq
group=root
# PID file
pid-file=/var/run/dnsmasq/dnsmasq.pid
all-servers
dns-forward-max=100
# TTL for auth replies
auth-ttl=600

# Logging
# ----------------------------------------------------------------------------
# Log to file
log-facility=/var/log/dnsmasq.log
# Log all queries
log-queries
# Query cache
cache-size=16384
# Asynchronous logging, up to 50 lines
log-async=50

# Config files and folders (DynDNS files)
# ----------------------------------------------------------------------------
# Do not read /etc/resolv.conf
no-resolv
# Do not poll /etc/resolv.conf
no-poll
# Do not read /etc/hosts
no-hosts
# Read *.conf from this folder
conf-dir=/var/www/ddns.example.com/dnsmasq/,*.conf

# Authoritative DNS on interface eth0
# ----------------------------------------------------------------------------
auth-server=yourdomain.tld,eth0

# My zones and their subnets
# ----------------------------------------------------------------------------
auth-zone=yourdomain.tld,10.20.30.40/32,ip:v6::ad::dr:ess/128
auth-zone=example.com,10.20.30.40/32,ip:v6::ad::dr:ess/128
# DDNS zone without subnet(s), contains "foreign" IPs
auth-zone=ddns.example.com
auth-zone=example.org,10.20.30.40/32,ip:v6::ad::dr:ess/128
auth-zone=example.net,10.20.30.40/32,ip:v6::ad::dr:ess/128
auth-zone=another-domain.de,10.20.30.40/32,ip:v6::ad::dr:ess/128

# Local (not forwarded in any case)
# ----------------------------------------------------------------------------
local=/example.com/10.20.30.40
domain=example.com
local=/ddns.example.com/10.20.30.40
domain=ddns.example.com
local=/example.org/10.20.30.40
domain=example.org
local=/example.net/10.20.30.40
domain=example.net
local=/another-domain.de/10.20.30.40
domain=another-domain.de

# SOA config
# ----------------------------------------------------------------------------
auth-soa=2016021014,hostmaster.example.com,1200,120,604800

# Slave NS: nameserver2.provider.com (50.60.70.80)
# ----------------------------------------------------------------------------
# Secondary NS (slave NS at provider)
auth-sec-servers=nameserver2.provider.com
# Allow zone transfers to secondary NS
auth-peer=50.60.70.80

# A/AAAA records - Only 1st address creates PTR record!
# ----------------------------------------------------------------------------
# MX: A/IPv4 only
host-record=mail.example.com,10.20.30.40
# ipv6.example.com: AAAA/IPv6 only
host-record=ipv6.example.com,ip:v6::ad::dr:ess
# All others: A/IPv4 and AAAA/IPv6
host-record=example.com,10.20.30.40,ip:v6::ad::dr:ess
host-record=ddns.example.com,10.20.30.40,ip:v6::ad::dr:ess
host-record=example.org,10.20.30.40,ip:v6::ad::dr:ess
host-record=example.net,10.20.30.40,ip:v6::ad::dr:ess
host-record=another-domain.de,10.20.30.40,ip:v6::ad::dr:ess
host-record=yourdomain.tld,10.20.30.40,ip:v6::ad::dr:ess
# Provide an A record for secondary NS
host-record=nameserver2.provider.com,50.60.70.80

# PTR & Reverse
# ----------------------------------------------------------------------------
server=/30.20.10.in-addr.arpa/10.20.30.40
ptr-record=40.30.20.10.in-addr.arpa,mail.example.com
ptr-record=40.30.20.10.in-addr.arpa,example.com
ptr-record=40.30.20.10.in-addr.arpa,ddns.example.com
ptr-record=40.30.20.10.in-addr.arpa,example.org
ptr-record=40.30.20.10.in-addr.arpa,example.net
ptr-record=40.30.20.10.in-addr.arpa,another-domain.de

# MX records
# ----------------------------------------------------------------------------
# All domains use MX mail.example.com
mx-host=yourdomain.tld,mail.example.com,10
mx-host=example.com,mail.example.com,10
mx-host=example.org,mail.example.com,10
mx-host=example.net,mail.example.com,10
mx-host=another-domain.de,mail.example.com,10

# TXT records (SPF, DKIM, fun etc.)
# ----------------------------------------------------------------------------
# A note for the MX
txt-record=mail.example.com,"No, this is not a Microsoft Exchange server..."
# SPF and DKIM records
txt-record=yourdomain.tld,"v=spf1 +a +mx -all"
txt-record=example.com,"v=spf1 +a +mx -all"
txt-record=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx._domainkey.example.com,"v=DKIM1; k=rsa; p=..."
txt-record=example.org,"v=spf1 +a +mx -all"
txt-record=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx._domainkey.example.org,"v=DKIM1; k=rsa; p=..."
txt-record=example.net,"v=spf1 +a +mx -all"
txt-record=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx._domainkey.example.net,"v=DKIM1; k=rsa; p=..."
txt-record=another-domain.de,"v=spf1 +a +mx -all"
txt-record=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx._domainkey.another-domain.de,"v=DKIM1; k=rsa; p=..."

# CAA record for certificate authority | https://sslmate.com/caa/
# ----------------------------------------------------------------------------
# CAA/257 => 0 issue "letsencrypt.org"
dns-rr=yourdomain.tld,257,000569737375656C657473656E63727970742E6F7267

# CNAME records
# ----------------------------------------------------------------------------
# Subdomains of example.com
cname=subdomain1.example.com,example.com
cname=subdomain2.example.com,example.com
cname=subdomain3.example.com,example.com
# www. and ftp. for all domains
cname=www.example.com,example.com
cname=ftp.example.com,example.com
cname=www.example.org,example.org
cname=ftp.example.org,example.org
cname=www.example.net,example.net
cname=ftp.example.net,example.net
cname=www.another-domain.de,another-domain.de
cname=ftp.another-domain.de,another-domain.de

Then set these DNS records on your registar panel:

1
2
3
4
A     yourdomain.tld     10.20.30.40
AAAA  yourdomain.tld     ip:v6::ad::dr:ess
NS    ns1.yourdomain.tld 10.20.30.40
NS    ns2.yourdomain.tld 10.20.30.40

please take note that you sould have two different dns servers in case the first goes down.


Source: onderka.com, manpage, stackexchange, SOA record, CAA record + tool

See also: Letsencrypt setup with acme.sh post.


~~~ * ~~~

Letsencrypt setup | Free automated SSL certificates
mouse 368 · person cloud · link
Last update
2019-03-07
2019
03-07
« — »

I chose acme.sh shell script among the available clients because it is simple to install and does not require any extra library.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# 1. install script:
git clone https://github.com/Neilpang/acme.sh.git acme.sh.repo

cd acme.sh.repo

DIR="$HOME/letsencrypt"
./acme.sh --install                           \
  --home          $DIR/acme.sh                \
  --certhome      $DIR/certs                  \
  --accountkey    $DIR/acme.sh/myaccount.key  \
  --accountconf   $DIR/acme.sh/myaccount.conf \
  --accountemail  "xxx@yyy.com"

exit # and reopen a shell

# 2. set autoupdate of the script:
acme.sh --upgrade --auto-upgrade

# 3. run it twice per day on a random minute, set crontab:
#    see: https://certbot.eff.org/#debianwheezy-nginx
10  0 * * * /path_to/acme.sh/acme.sh --cron --home /path_to/acme.sh > /dev/null
20 12 * * * /path_to/acme.sh/acme.sh --cron --home /path_to/acme.sh > /dev/null

# 4a. issue a certificate (add --test for the staging environment):
acme.sh --issue -d acavalin.com -d www.acavalin.com -w /path_to/webserver_public_root

# 4b. issue a wildcard certificate with a specific dns service plugin
acme.sh --issue -d acavalin.com -d '*.acavalin.com' --dns dns_plugin_name

# 5. install certificate for NGINX (do not manually copy acme.sh files!):
acme.sh --install-cert -d acavalin.com \
  --key-file       /path_to/ssl_app.key \
  --fullchain-file /path_to/ssl_app.crt \
  --reloadcmd      "/path_to/server_script.sh restart"

All commands will update the configuration files present in --home and --certhome, and every issued certificate will be valid for 60 days by default.

For wildcard certificates you can configure dnsmasq as an authoritative dns server and then use this plugin in step 4b via --dns dns_dnsmasq to issue your certificate:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/usr/bin/env sh
# acme.sh plugin @ $HOME/letsencrypt/acme.sh/dnsapi/dns_dnsmasq.sh

CONF=/etc/dnsmasq.d/acme-challenge.conf

dns_dnsmasq_add() {
  echo "txt-record=$1,\"$2\"" >> $CONF
  systemctl restart dnsmasq ; sleep 1
}

dns_dnsmasq_rm() {
  sed -i "/$1,.$2./d" $CONF
  systemctl restart dnsmasq ; sleep 1 # optional
}

Reference: Let's Encrypt HP and acme.sh

Wildcard cert: issue example, dns api ref, dns api dev guide, dns manual and alias mode, acme-dns


~~~ * ~~~

UFW firewall setup
mouse 463 · person cloud · link
Last update
2019-03-06
2019
03-06
« — »

If you are using it on a VPS then you have to enable iptables NAT beforehand.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
apt-get install ufw

# write rules in /lib/ufw/user.rules
ufw reset # reset to defaults
# set our defaults
ufw default allow outgoing
ufw default deny  incoming
ufw allow 22/tcp        # ssh
ufw allow 80/tcp        # http
ufw allow 443/tcp       # https
ufw allow 1194/udp      # openvpn
ufw allow 1100:1200/tcp # port range (proto required23)
ufw allow 53            # allow both tcp and udp (eg: DNS)
ufw allow from 1.2.3.4  # single host
ufw allow from 192.168.1.0/24 # subnet
ufw allow from 1.2.3.4 to any port 22 proto tcp

# block an IP if it has attempted to initiate 6 or more
# connections in the last 30 seconds
ufw limit 22/tcp

# show rules added before enabling firewall
ufw show added

# remove rule
ufw status numbered
ufw delete row_number

# show rules
ufw show added
ufw show raw

# other reports
ufw show builtins
ufw show before-rules
ufw show user-rules
ufw show after-rules
ufw show logging-rules

# start/stop/status service
ufw enable
ufw disable
ufw status
ufw status verbose
ufw reload # reload cfg

# see logs
ufw logging low # off/low/medium/high/full
tail -f /var/log/ufw.log

Note: The order of rules is critical in ufw/iptables as a packet will match the first rule, subsequent rules are ignored.


Source: CyberCiti, ArchLinux

See also: Lullabot


~~~ * ~~~

Docker howto attachment
Last update
2019-03-05
2019
03-05
« — »

Installation on debian

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# check system compatibility
wget -q -O - https://raw.githubusercontent.com/docker/docker/master/contrib/check-config.sh | \
  bash | tee docker-check.txt

# install docker: key, repo, packages
apt-get install apt-transport-https ca- curl gnupg2 software-properties-common
curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add -

# echo "deb [arch=amd64] https://download.docker.com/linux/debian stretch stable" > /etc/apt/sources.list.d/docker-ce.list # armhf @ raspi
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable" # armhf @ raspi

apt-get update && apt-get install docker-ce

# allow user to use docker
usermod -aG docker username

# test installation
docker version
docker info

# run a simple test image
docker run hello-world

See also post install for troubleshooting dns/network/remote access.

On raspberry pi just use curl -sSL https://get.docker.com | sh (repo not working).

Creating an image (ref, best practices)

1
2
3
4
5
6
7
8
9
10
11
12
touch Dockerfile # and fill it
docker build -t test-myimg . # create the image with a tag

# test run image
docker run -p 4000:80    test-myimg
docker run -it test-myimg /bin/bash

# run image detached/on background
docker run -p 4000:80 -d --name tmi test-myimg
docker container ls -a
docker container stop <container_id>
docker container start -i tmi # restart container

Interact (ref)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# run interactive shell into debian image (temporary)
docker run --name prova --rm -it debian /bin/bash 

# run interactive shell into debian image
docker run -it debian /bin/bash 

apt-get update

apt-get install -y dialog nano ncdu
apt-get install -y locales

localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8
echo "LANG=en_US.utf8" >> /etc/environment

rm -rf /var/lib/apt/lists/*

docker commit e2b7329257ba myimg:v1

docker run --rm -it myimg:v1 /bin/bash

# run a command in a running container
docker exec -ti a123098734e bash -il

docker stop a123098734e
docker kill a123098734e

Save & restore

1
2
3
4
5
docker save imgname | gzip > imgname.tgz
zcat imgname.tgz | docker load

# flatten image layers (losing Dockerfile)
docker export <id> | docker import - imgname:tag

Registry - Image repository

1
2
3
4
5
# push image to gitlab registry
docker login registry.gitlab.com
docker tag test-myimg registry.gitlab.com/username/repo:tag # add new tag...
docker rmi test-myimg # ...and remove the old tag
docker push registry.gitlab.com/username/repo:tag

DockerHub official base images links: debian, ruby, rails, redis, nginx.

Available free registry services:

Name # Priv/Pub Notes
gitlab inf/ND 1 prj x registry
treescale inf/inf max 500 pulls & 50GB
canister 20/ND very good service
docker hub 1/inf perfect

Running arm image on x86

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# https://ownyourbits.com/2018/06/27/running-and-building-arm-docker-containers-in-x86/
apt-get install qemu-user-static

docker run \
  -v /usr/bin/qemu-arm-static:/usr/bin/qemu-arm-static \
  -e LANG=en_US.utf8 -ti --name myarmimg arm32v7/debian:wheezy

[...]

docker commit myarmimg myarmimg

docker container prune -f

docker run \
  -v /usr/bin/qemu-arm-static:/usr/bin/qemu-arm-static \
  -ti --rm --name myarmimg \
  myarmimg /bin/bash -il

Composer (ref, dl) - Services

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# docker-compose.yml
version: "3"
services:
  web:
    image: username/repo:tag
    deploy:
      replicas: 5
      resources:
        limits:
          cpus: "0.1"
          memory: 50M
      restart_policy:
        condition: on-failure
    ports:
      - "4000:80"
    networks:
      - webnet
networks:
  webnet:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# install docker-compose
curl -L  -o /usr/local/bin/docker-compose https://github.com/docker/compose/releases/download/1.24.0-rc1/docker-compose-`uname -s`-`uname -m`
chmod 755 /usr/local/bin/docker-compose

docker swarm init

docker stack deploy --with-registry-auth -c docker-compose.yml getstartedlab
docker service ls
docker service ps getstartedlab_web # or docker stack ps getstartedlab

# change the yml file and restart service
docker stack deploy --with-registry-auth -c docker-compose.yml getstartedlab
docker service ps getstartedlab_web
docker container prune -f

# stop & destroy service
docker stack rm getstartedlab
docker container prune -f

# leave the swarm
docker swarm leave --force

Machine (ref, dl) - SWARM/Provisioning

Without an official supported driver we can use the generic one. Install docker-ce on your worker nodes and then in your swarm manager host:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# install docker-machine
curl -L -o /usr/local/bin/docker-machine https://github.com/docker/machine/releases/download/v0.16.1/docker-machine-`uname -s`-`uname -m`
chmod 755 /usr/local/bin/docker-machine

# setup each VMs
ssh-copy-id -i ~/.ssh/id_rsa user@ww.xx.yy.zz
docker-machine create --driver generic --generic-ssh-key ~/.ssh/id_rsa \
  --generic-ip-address=ww.xx.yy.zz myvm1

ssh-copy-id -i ~/.ssh/id_rsa user@ww.xx.yy.kk
docker-machine create --driver generic --generic-ssh-key ~/.ssh/id_rsa \
  --generic-ip-address=ww.xx.yy.kk myvm2

docker-machine ls

# run a command via ssh in a VM
docker-machine ssh myvm1 "ls -l"                 # use internal SSH lib
docker-machine --native-ssh ssh myvm1 "bash -il" # use system SSH lib

# set env to run all docker commands remotely on a VM
eval $(docker-machine env myvm1) # on bash
docker-machine use myvm1         # on fish + omf plugin-docker-machine

# set VM1 to be a swarm manager
docker-machine use myvm1
docker swarm init # --advertise-addr ww.xx.yy.zz
docker swarm join-token worker # get token for adding worker nodes

# set VM2 to join the swarm as a worker
docker-machine use myvm2
docker swarm join --token SWMTKN-xxx ww.xx.yy.zz:2377

# check cluster status on your local machine...
docker-machine ls
# ...or on the manager node
docker-machine use myvm1
docker node ls

# locally login on your registry...
docker-machine unset
docker login registry.gitlab.com
# ...then deploy the app on the swarm manager
docker-machine use myvm1
docker stack deploy --with-registry-auth -c docker-compose.yml getstartedlab
docker service ls
docker service ps getstartedlab_web

# access cluster from any VM's IP
curl http://ww.xx.yy.zz:4000
curl http://ww.xx.yy.kk:4000

# eventually re-run "docker stack deploy ..." to apply changes

# undo app deployment
docker-machine use myvm1
docker stack rm getstartedlab

# remove the swarm
docker-machine run myvm2 "docker swarm leave"
docker-machine run myvm1 "docker swarm leave --force"

If using fish shell you can install the useful omf plugin-docker-machine.

Stack / Deploy application

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# docker-compose.yml
version: "3"
services:
  web:
    image: username/repo:tag
    deploy:
      replicas: 5
      restart_policy:
        condition: on-failure
      resources:
        limits:
          cpus: "0.1"
          memory: 50M
    ports:
      - "80:80"
    networks:
      - webnet
  visualizer:
    image: dockersamples/visualizer:stable
    ports:
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
    deploy:
      placement:
        constraints: [node.role == manager]
    networks:
      - webnet
  redis:
    image: redis
    ports:
      - "6379:6379"
    volumes:
      - "/home/docker/data:/data"
    deploy:
      placement:
        constraints: [node.role == manager]
    command: redis-server --appendonly yes
    networks:
      - webnet
networks:
  webnet:
1
2
3
4
5
6
7
8
9
10
11
docker-machine use myvm1
docker-machine ssh myvm1 "mkdir ./data" # create redis data folder

# run stack / deploy app
docker stack deploy -c docker-compose.yml getstartedlab
docker stack ps getstartedlab

firefox http://<myvm1-ip>:8080/ # docker visualizer
redis-cli -h <myvm1-ip>         # interact with redis

docker stack rm getstartedlab

Terms:

  • service = containers that only runs one/same image,
  • task = a single container running in a service,
  • swarm = a cluster of machines running Docker,
  • stack = a group of interrelated services orchestrated and scalable, defining and coordinating the functionality of an entire application.

Source: tutorial, overview, manage app data, config. daemon, config. containers

Useful tips: cleanup