Skip to content

Instantly share code, notes, and snippets.

@semachka
Last active Sep 7, 2022
Embed
What would you like to do?
Commands

Powerlevel10k

- git clone --depth=1 https://github.com/romkatv/powerlevel10k.git ~/powerlevel10k
- echo 'source ~/powerlevel10k/powerlevel10k.zsh-theme' >>~/.zshrc

Intellij Mono

- https://www.jetbrains.com/lp/mono/
#! /bin/bash
# install git
sudo apt-get install git
alias python=python3
# install gestures
sudo apt install python3 python3-gi python-gobject meson xdotool libinput-tools gettext
sudo gpasswd -a $USER input
git clone https://github.com/bulletmark/libinput-gestures.git && cd libinput-gestures
sudo make install && sudo ./libinput-gestures-setup install
libinput-gestures-setup start && libinput-gestures-setup autostart
## installing the UI part
git clone https://gitlab.com/cunidev/gestures && cd gestures
sudo apt-get install appstream-util && sudo apt-get install python3-setuptools
meson build --prefix=/usr && ninja -C build && sudo ninja -C build install
## Manually install
https://extensions.gnome.org/extension/1485/workspace-matrix/
unzip ~/Downloads/wsmatrixmartin.zurowietz.de*.zip -d ~/.local/share/gnome-shell/extensions/wsmatrix@martin.zurowietz.d
gnome-extensions enable wsmatrixmartin@zurowietz.de
#####################################################################################
# install zsh + oh-my-zsh
sudo apt install zsh && sudo apt install git-core curl fonts-powerline
sh -c "$(curl -fsSL https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"
# install brew (need for terragrunt)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
echo 'eval $(/home/linuxbrew/.linuxbrew/bin/brew shellenv)' >> /home/$USER/.zprofile
echo 'eval $(/home/linuxbrew/.linuxbrew/bin/brew shellenv)' >> /home/$USER/.zshrc
eval $(/home/linuxbrew/.linuxbrew/bin/brew shellenv)
# install terminator
sudo add-apt-repository ppa:gnome-terminator
sudo apt-get update
sudo apt-get install terminator
# install terraform and terragrunt
apt-get install terraform && brew install terragrunt
# install docker
sudo apt-get install docker-ce docker-ce-cli containerd.io
# install kubectl
sudo apt-get update && sudo apt-get install -y apt-transport-https ca-certificates curl
sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg
echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update && sudo apt-get install -y kubectl
# install awscli
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip && sudo ./aws/install
# install SSM
curl "https://s3.amazonaws.com/session-manager-downloads/plugin/latest/ubuntu_64bit/session-manager-plugin.deb" -o "session-manager-plugin.deb"
sudo dpkg -i session-manager-plugin.deb
# install tableplus
wget -qO - http://deb.tableplus.com/apt.tableplus.com.gpg.key | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://deb.tableplus.com/debian/21 tableplus main"
sudo apt update && sudo apt upgrade
# install intellij toolbox + vscode
sudo apt update
sudo apt install mysql-client
#! /bin/bash
# Powerlevel10k
git clone --depth=1 https://github.com/romkatv/powerlevel10k.git ~/powerlevel10k
echo 'source ~/powerlevel10k/powerlevel10k.zsh-theme' >>~/.zshrc
# Intellij Mono
wget https://www.jetbrains.com/lp/mono/ -P /Users/${$USER}/fonts
# https://github.com/natesales/q
git clone https://github.com/natesales/q && cd q
go install

STS get session credentials

- aws sts assume-role --role-arn arn:aws:iam::{{ ACCOUNT }}:role/{{ ROLE ID}} --role-session-name something --query '[Credentials.SessionToken,Credentials.AccessKeyId,Credentials.SecretAccessKey]' --output text

Delete all unused secrets

docker secret rm $(docker secret ls -q)

Important PORTS

4789 TCP	swarm container ingress
7946 UDP	swarm network discovery
2377 TCP	swarm ingress port
7946 TCP	swarm network discovery

Container Network information

docker inspect -f '{{range $key, $value := .NetworkSettings.Networks}}{{$key}} {{end}}' [CONTAINER_ID_HERE]

List all containers belonging to a network by name

docker network inspect -f '{{range .Containers}}{{.Name}} {{end}}' [NETWORK_ID_HERE]

Get a container's IP address inside a specific network

docker inspect -f '{{.NetworkSettings.Networks.[network].IPAddress}}' [CONTAINER_ID_HERE]
docker inspect -f '{{ $network := index .NetworkSettings.Networks "[network]" }}{{ $network.IPAddress}}' [CONTAINER_ID_HERE]

Scale containers to 1000

docker swarm init --default-addr-pool 192.168.0.0/16 --default-addr-pool-mask-length 20
docker network create --driver overlay --subnet 20.30.0.0/20 --attachable party-swarm
docker service create --replicas 1000 --network party-swarm --update-parallelism 5 --name sonyflake -p 8080:8080 titpetric/sonyflake
# docker service ls    
Reference: https://www.cloudbees.com/blog/running-1000-containers-in-docker-swarm

count how many containers are running

docker node ps $(docker node ls -q) --filter desired-state=Running | uniq | wc

Cleanup Branches Locally

- git branch -D $(git branch)

User management

- OneLine: useradd -m semion.k && usermod -aG wheel semion.k && passwd semion.k
- useradd -m {{ username }}
  - -m: with directory
- userdel -r {{ username }}
  - -r: remove home directory
- passwd {{ username }}
  - create password
- usermod -aG {{ wheel or sudo group}} semion.k

User Management

  • CREATE USER 'sammy'@'%' IDENTIFIED WITH mysql_native_password BY 'password';

  • CREATE USER 'milkpayui'@'%' IDENTIFIED WITH mysql_native_password BY 'xnq2vcy-gnw-PFD4nmj';

  • RENAME USER 'milkpayui'@'localhost' TO 'milkpayui'@'%';

  • GRANT CREATE, INSERT, UPDATE, DELETE, SELECT on milkpayui.* TO 'milkpayui'@'%' WITH GRANT OPTION;

  • FLUSH PRIVILEGES;

  • grant usage on . to 'semion_kopachevsky'@'%'

  • FLUSH PRIVILEGES;

Change password

- ALTER USER 'pavel_svushkin'@'milkpayui' IDENTIFIED BY 'eny_kgd_tej2zrk!THX';

Whitelisting User IPS (if user is using bastion, need to whitelist that one as well.)

- UPDATE mysql.user SET Host='184.144.194.172' where User = 'semion_kopachevsky';
- UPDATE mysql.user SET Host='%' where User = 'semion_kopachevsky';
- FLUSH PRIVILEGES;

Information

Basic information

- select * from information_schema.USER_PRIVILEGES
- select * from information_schema.TABLE_PRIVILEGES

User information

- SELECT User,Host FROM mysql.user;
- select * from mysql.user;
- SHOW GRANTS FOR 'milkpayui'

Find database sizes

- Megabytes
    SELECT table_schema AS "Database", SUM(data_length + index_length) / 1024 / 1024 AS "Size (MB)" FROM information_schema.TABLES GROUP BY table_schema
- Gigabytes
    SELECT table_schema AS "Database", SUM(data_length + index_length) / 1024 / 1024 / 1024 AS "Size (GB)" FROM information_schema.TABLES GROUP BY table_schema

Server Management

Root reset password > version 8

- systemctl stop mysqld
- systemctl set-environment MYSQLD_OPTS=--skip-grant-table_schema
- systemctl stat mysqld
- UPDATE mysql.user SET authentication_string=null WHERE User='root';
- FLUSH PRIVILEGES;
- ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'new_password';
- FLUSH PRIVILEGES;
- exit;
- systemctl stop mysqld
- systemctl unset-environment MYSQLD_OPTS
- systemctl start mysqld

Slave information

- SHOW SLAVE HOSTS
- SELECT * FROM information_schema.PROCESSLIST AS p WHERE p.COMMAND = 'Binlog Dump';
- 

nmap LoadBalancer

-  nmap -v -Pn -sT public-us-east-1-1146088445.us-east-1.elb.amazonaws.com
-  nmap -sL pulse.aezai.com

List SSL DNS name

``` true | openssl s_client -connect 35.173.167.52:443 2>/dev/null \

| openssl x509 -noout -text
| perl -l -0777 -ne '@names=/\bDNS:([^\s,]+)/g; print join("\n", sort @names)
```

Flow

nmap -sL pulse.aezai.com
    ec2-35-173-167-52.compute-1.amazonaws.com
            curl -v https://35.173.167.52:443
        nmap -p 443 --script ssl-cert 35.173.167.52
        openssl s_client -showcerts -connect 35.173.167.52:443
proto udp4
dev tun0
ca ca.crt
cert server.crt
key server.key
dh dh.pem
auth SHA512
topology subnet
server 10.8.0.0 255.255.255.0
push "redirect-gateway def1 bypass-dhcp"
ifconfig-pool-persist ipp.txt
push "dhcp-option DNS 1.1.1.1"
push "dhcp-option DNS 1.0.0.1"
keepalive 10 120
cipher AES-256-CBC
tls-crypt tc.key
user nobody
group nogroup
persist-key
persist-tun
verb 3
compress comp-lzo
explicit-exit-notify
data-ciphers-fallback AES-256-CBC
status /var/log/openvpn/status.log
log-append /var/log/openvpn/connections.log

experimented on RaspberryPI (Reference https://wiki.calculate-linux.org/openvpn && https://raspberrytips.com/openvpn-raspberry-pi/)

Legend

CA Authority: Server holding the autohority keys and which generates the server and client certificates
Server: the server VPN which will hold server specific certificates
Client: The client certificate AKA {{ file.ovpn }}

OPENVPN

- Method 1 (Installed this flow on raspberrypi and used the generated files from flow 2.): 
  - Install openvpn with certificate
    - wget https://git.io/vpn -O openvpn-install.sh
       - chmod +x openvpn-install.sh
          - sudo ./openvpn-install.sh
  - Service management
    - sudo systemctl status openvpn-server@server.service
    - sudo systemctl restart openvpn-server@server.service

  - Log Monitoring
    - tail -fn500 /var/log/syslog
    - journalctl -f --unit=openvpn
    - tail -fn500 /var/log/openvpn/connections.log
    - tail -fn500 /var/log/openvpn/connections.log

  - IP Manaement
    - sudo iptables -L
    - ifconfig
---------------------------------------------------------------------------------------------------------
- Method 2:
  - Download: https://github.com/OpenVPN/easy-rsa
    - cd ./easyrsa && cp vars.example vars
      - #set_var EASYRSA_REQ_COUNTRY    "CA"
        #set_var EASYRSA_REQ_PROVINCE   "Quebec"
        #set_var EASYRSA_REQ_CITY       "Montreal"
        #set_var EASYRSA_REQ_ORG        "jumanji Tech Ltd"
        #set_var EASYRSA_REQ_EMAIL      "it@jumanji.io"
        #set_var EASYRSA_REQ_OU         "Jumanji"
    - ./easyrsa init-pki
    - ./easyrsa build-ca nopass
    - ./easyrsa build-server-full server nopass
    - ./easyrsa build-client-full client nopass
      - CAN BE REPLACE BY OVPN CLIENT FILE (SEE BELLOW)
    - ./easyrsa gen-dh
    - openvpn --genkey --secret pki/ta.key

  - RSYNC to the server the following files
    - rsync -a /easyrsa3/pki/ca.crt {{ USER }}@{{ SERVER_IP }}:/etc/openvpn/keys/
    - rsync -a /easyrsa3/pki/dh.pem {{ USER }}@{{ SERVER_IP }}:/etc/openvpn/keys/
    - rsync -a /easyrsa3/pki/issued/server.crt {{ USER }}@{{ SERVER_IP }}:/etc/openvpn/keys/
    - rsync -a /easyrsa3/pki/private/server.key {{ USER }}@{{ SERVER_IP }}:/etc/openvpn/keys/
    - rsync -a /easyrsa3/pki/ta.key {{ USER }}@{{ SERVER_IP }}:/etc/openvpn/keys/
  
  - GENERATE CLIENT OPVN FILE (REPLACEMENT FOR KEYS METHOD)
    - echo '<ca>' >> client.ovpn\n
    - cat /easyrsa3/pki/ca.crt >> client.ovpn
    - cho '</ca>' >> client.ovpn
    - echo '</ca>' >> client.ovpn
    - echo '<cert>' >> client.ovpn
    - cat /easyrsa3/pki/issued/client.crt >> client.ovpn
    - echo '</cert>' >> client.ovpn
    - echo '<key>' >> client.ovpn
    - cat /easyrsa3/pki/private/client.key >> client.ovpn\n
    - echo '</key>' >> client.ovpn\n
    - echo '<tls-auth>' >> client.ovpn\n
    - cat /easyrsa3/pki/ta.key >> client.ovpn\n
    - echo '</tls-auth>' >> client.ovpn

EasyRSA Commands

- ./easyrsa show-cert client
- ./easyrsa revoke client
- cat pki/index.txt

EXAMPLE FILES

- openvpn.sh
  - script to install openvpn and generate keys
- openvpn.ovpn
  - client certificate ovpn example
- openvpn.conf
  - server config example.

SPEED TEST: curl -s https://raw.githubusercontent.com/sivel/speedtest-cli/master/speedtest.py | python -

client
proto udp4
dev tun0
# compress comp-lzo
remote raspberrypi.local 1194
persist-tun
persist-key
key-direction 1
# remote-cert-tls server // tls-crypt tc.key
<ca>
-----BEGIN CERTIFICATE-----
MIIDODCCAiCgAwIBAgIJAJi2P0UW7o+qMA0GCSqGSIb3DQEBCwUAMBcxFTATBgNV
BAMMDHJlZGR0ZWNoLXZwbjAeFw0yMjA5MDEyMDA1MDdaFw0zMjA4MjkyMDA1MDda
MBcxFTATBgNVBAMMDHJlZGR0ZWNoLXZwbjCCASIwDQYJKoZIhvcNAQEBBQADggEP
ADCCAQoCggEBAKjvs0RfqyC2gIIJ5G9tulEDKOMDRC4+RRZ29yvUWCreBMMrx7FD
03QsY2N4AmHniKKJ4ZVr2BdpLHcQyPJGc67LO/Uw/2RPw4pBP/ToqLZ5R4fm5lWL
9Wxu0SrO2wthjSAIuKv+6/anxLL+nDMTutet0CN3HN//gboLw58T9B8mtsewsY2h
r0u6ZBJM/7AyIc/A3NYt3ZfIovybvlr2+pF8Zn08XTe/kUu+Ay8DS2cqZFRqjd/z
YQiqvE/YAdQLqoWlDHUzmvSwuQJKRmpYJmRKnJ0/R7clZvYJ8zpvT6l4VLoLA93j
PQOBHT5WUvxy4bazaiHv3pta4iRUhjxar7cCAwEAAaOBhjCBgzAMBgNVHRMEBTAD
AQH/MB0GA1UdDgQWBBRkz7hjWcWN0mR4IeG3jBZnM/IZfjBHBgNVHSMEQDA+gBRk
z7hjWcWN0mR4IeG3jBZnM/IZfqEbpBkwFzEVMBMGA1UEAwwMcmVkZHRlY2gtdnBu
ggkAmLY/RRbuj6owCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQCE8lHD
tmtchJvi5zpLcX9a460kiPtcoJgR8jzUdqKdSsoiwTfscptgJtLyehm7JPo0tjtz
xZiAPDwCrX7dhD0GSEghsIXu4J1+lZHmiCqtJoPwQje2c0jVMw61Y9w0QhjoaXib
7gtHtYqO7iwef75djh9YEsEuCrsAp/hNkgTYTXku9yO0C1/lxAYPn3J2+QGWdDsg
cyS5NyHhh+CMWhijDPRw7g7T/IhWVY9tWwYm6MaXgpcfHDki0blS8JqR8CfzF3YX
f4mwPeqzEny2mymUOGaZS4AqhEoJ+eIBn3PPKTpt1WCF95E4u9251ZaD+0gxw9mq
yLuhv3LJcqgxWQnF
-----END CERTIFICATE-----
</ca>
<cert>
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
1a:37:89:e2:4e:bc:bf:6b:63:b9:82:e3:ad:92:62:40
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=reddtech-vpn
Validity
Not Before: Sep 1 20:17:46 2022 GMT
Not After : Dec 4 20:17:46 2024 GMT
Subject: CN=client
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:db:f1:de:4a:b5:1d:db:f4:b0:e9:f2:c1:fb:4f:
a6:8d:47:c6:59:37:c4:97:f1:bf:7c:01:0c:ed:ff:
67:9d:7e:43:cc:db:18:92:c0:80:98:56:50:52:00:
b7:f9:89:ff:e5:07:5c:37:39:ff:95:1a:1b:d3:4f:
81:c8:e7:7d:a4:d2:05:77:b2:54:16:a7:6f:43:5a:
3b:83:58:77:7c:66:24:6b:96:af:a7:93:b8:8c:6f:
38:43:7f:a8:c9:34:67:8b:0e:23:b5:36:93:ca:57:
63:e6:d0:be:7b:df:53:3e:fe:14:2b:e3:d6:fd:ea:
f6:7f:7c:b6:4d:55:01:03:80:a9:78:3f:d7:2f:88:
a2:32:48:89:d1:78:c5:38:03:6d:05:83:ad:52:6c:
eb:52:0b:a7:bd:04:e7:b6:59:53:14:ff:c0:ab:3e:
c5:b5:00:5d:78:8b:56:c6:9c:5a:94:b2:cd:9e:20:
ef:98:d5:b9:1b:45:5c:12:9a:ba:aa:5b:1b:71:5e:
f6:bb:33:9a:87:ca:e4:3e:f3:0c:08:bf:b0:55:50:
20:a2:e8:27:50:5e:82:5d:03:e2:f5:44:14:99:e2:
8e:6d:8f:68:54:d5:bf:38:a6:58:e1:47:9a:77:e3:
82:fa:f9:a4:da:34:62:0a:a5:cf:84:71:65:7c:89:
cc:71
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
X509v3 Subject Key Identifier:
B9:20:39:C1:02:9B:95:81:21:C8:57:F4:12:26:17:A3:21:6F:6E:80
X509v3 Authority Key Identifier:
keyid:64:CF:B8:63:59:C5:8D:D2:64:78:21:E1:B7:8C:16:67:33:F2:19:7E
DirName:/CN=reddtech-vpn
serial:98:B6:3F:45:16:EE:8F:AA
X509v3 Extended Key Usage:
TLS Web Client Authentication
X509v3 Key Usage:
Digital Signature
Signature Algorithm: sha256WithRSAEncryption
3f:57:09:ef:a4:59:ca:10:38:0d:c4:90:75:e7:17:ec:c8:80:
e0:35:24:ab:a8:f7:8a:0b:50:52:89:76:31:7c:a9:6c:0c:82:
e4:40:22:5d:35:93:65:23:9c:71:7b:9d:aa:94:ff:63:e3:00:
e7:bc:95:2c:59:e2:31:f7:08:27:fe:87:c1:49:e1:88:9f:fd:
7d:6e:09:4b:62:c8:e4:17:b6:0e:e3:b5:09:92:97:57:d6:13:
c5:95:11:93:5e:aa:83:c8:52:eb:63:80:fe:85:c9:3a:d8:76:
cd:49:2f:da:ea:73:9a:a5:4c:f3:d8:ef:7f:36:cd:d1:09:f6:
00:bf:cb:38:bb:2c:d6:08:dc:11:9e:5f:76:31:65:9c:04:53:
5b:ae:9c:39:8b:c0:1f:49:82:7a:c7:ff:91:ad:c9:08:17:aa:
39:fd:4a:40:f3:e3:b0:af:61:cd:b7:45:fd:4b:e5:42:c6:ad:
da:5e:49:dc:2b:af:fb:5e:53:92:00:d5:90:91:a3:8d:44:d4:
7d:32:63:ca:20:43:19:3c:c5:23:ac:ef:c8:91:1b:98:1a:8a:
40:b7:d9:3d:da:ad:f9:4d:23:18:f0:5c:2f:10:f3:76:e2:54:
a9:b2:10:2f:65:d6:c5:56:03:f1:b5:7b:b7:98:a4:a6:ca:c9:
44:06:fd:5d
-----BEGIN CERTIFICATE-----
MIIDSzCCAjOgAwIBAgIQGjeJ4k68v2tjuYLjrZJiQDANBgkqhkiG9w0BAQsFADAX
MRUwEwYDVQQDDAxyZWRkdGVjaC12cG4wHhcNMjIwOTAxMjAxNzQ2WhcNMjQxMjA0
MjAxNzQ2WjARMQ8wDQYDVQQDDAZjbGllbnQwggEiMA0GCSqGSIb3DQEBAQUAA4IB
DwAwggEKAoIBAQDb8d5KtR3b9LDp8sH7T6aNR8ZZN8SX8b98AQzt/2edfkPM2xiS
wICYVlBSALf5if/lB1w3Of+VGhvTT4HI532k0gV3slQWp29DWjuDWHd8ZiRrlq+n
k7iMbzhDf6jJNGeLDiO1NpPKV2Pm0L5731M+/hQr49b96vZ/fLZNVQEDgKl4P9cv
iKIySInReMU4A20Fg61SbOtSC6e9BOe2WVMU/8CrPsW1AF14i1bGnFqUss2eIO+Y
1bkbRVwSmrqqWxtxXva7M5qHyuQ+8wwIv7BVUCCi6CdQXoJdA+L1RBSZ4o5tj2hU
1b84pljhR5p344L6+aTaNGIKpc+EcWV8icxxAgMBAAGjgZgwgZUwCQYDVR0TBAIw
ADAdBgNVHQ4EFgQUuSA5wQKblYEhyFf0EiYXoyFvboAwRwYDVR0jBEAwPoAUZM+4
Y1nFjdJkeCHht4wWZzPyGX6hG6QZMBcxFTATBgNVBAMMDHJlZGR0ZWNoLXZwboIJ
AJi2P0UW7o+qMBMGA1UdJQQMMAoGCCsGAQUFBwMCMAsGA1UdDwQEAwIHgDANBgkq
hkiG9w0BAQsFAAOCAQEAP1cJ76RZyhA4DcSQdecX7MiA4DUkq6j3igtQUol2MXyp
bAyC5EAiXTWTZSOccXudqpT/Y+MA57yVLFniMfcIJ/6HwUnhiJ/9fW4JS2LI5Be2
DuO1CZKXV9YTxZURk16qg8hS62OA/oXJOth2zUkv2upzmqVM89jvfzbN0Qn2AL/L
OLss1gjcEZ5fdjFlnARTW66cOYvAH0mCesf/ka3JCBeqOf1KQPPjsK9hzbdF/Uvl
Qsat2l5J3Cuv+15TkgDVkJGjjUTUfTJjyiBDGTzFI6zvyJEbmBqKQLfZPdqt+U0j
GPBcLxDzduJUqbIQL2XWxVYD8bV7t5ikpsrJRAb9XQ==
-----END CERTIFICATE-----
</cert>
<key>
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDb8d5KtR3b9LDp
8sH7T6aNR8ZZN8SX8b98AQzt/2edfkPM2xiSwICYVlBSALf5if/lB1w3Of+VGhvT
T4HI532k0gV3slQWp29DWjuDWHd8ZiRrlq+nk7iMbzhDf6jJNGeLDiO1NpPKV2Pm
0L5731M+/hQr49b96vZ/fLZNVQEDgKl4P9cviKIySInReMU4A20Fg61SbOtSC6e9
BOe2WVMU/8CrPsW1AF14i1bGnFqUss2eIO+Y1bkbRVwSmrqqWxtxXva7M5qHyuQ+
8wwIv7BVUCCi6CdQXoJdA+L1RBSZ4o5tj2hU1b84pljhR5p344L6+aTaNGIKpc+E
cWV8icxxAgMBAAECggEALAm3mnm9KsdJjO4gTPNbw7n1SvPRlyK+VlPXhOe4lV4s
sR3FQ8zrcpUFrAWc0IgDBpZ8rkoclHwPyjWHJPTEwXWTxq2cDJUlv/SXKetSsUO6
UxhuvzzinKvANjOfVfn6KWuBVs1AtijdRd/R4/eJMXmqDEeoSlr7U/digQVeGJcR
DJ+xAjkp7bUi8B8e8WVKloGSsIytq0Ire6qKFnGGgzhk9cIu7AnrVYkDz9Mv52l4
aiflZaLsclU4hfN1+U6ido9qQ5OKrmx92AWWfpFBx/sEAa5aNbDUjOQYXRCxA/hU
QSXnlYWn6NY32q+rn0QbPaSQTQWHxkovaMrAJF/CSQKBgQD/3taRCD4X9LcNZgRX
DitIefHBX5Y7YEYXX3xv13r7gPLy1ftjxr9PoXdcDiMWhXo1eD/eGXQtvT4qAHc0
NnOys5cLTF7UOjtK6qgXakAyLhv2lFc0Ag5rpe9IZ08/Khac64fc0GE5ioN/v507
YATs2K8WjLp7LRmGqYZC7meQJwKBgQDcDl/CvbQy8HJ0KY0vr1JjSnHxNrQ6z/Il
xSpmSwkCduywNw9ljhikqDXINt+7y51D6hjLn+qJWlPtnBG7+JgC10Mpr+Dxfz9f
Loi2L8S+ZHJ6G/FKAQk5/kbLxe1hMBeigXrognDnkWCF2Tews5jtvDkJpeUv31f3
e43m1cYFpwKBgAp4mhtRVQkx8JPRyvetEsRiiSw6tzEy3Wtzcuo4zUWhn0+kxibt
KUMe/n177p+rUrcBdsumCwUcK4EYh8hROibkBphlxbO1tlt4guyCYqIrFOXgaDku
pFxva/1wjOOu20IMuYCl3nS2YG9H7i1R3qG6tF+d3rvPuq2yHlZ63y4dAoGAVx6x
ts2X+9rJ1UdmCAznFzwv5Al+TRJqkZ1/bcQjKwCeMB18UP5yry2RLVTcOuMfvfV+
H4+OMRa7x4RUWRDQTb+fbW+eJL31/t7TbR14TNBDqihJ3LyQRI9ww9f2ZNW/ZazR
Vh/eRy99AUDAFYrk7qnoAvPUyqEnmGkoAs17el0CgYEAtfLEu0fr0+LCpUW6821U
d42KxQtc/9XdLLxX5Bn57a526udwM01UsWm+iLz5apM1UPxy8G8E2eMWtqo4aciC
GRDRC6SUIEbEzJiZxy1KLLgEadkuY7ywaXhiBn/MSXeOzsFvKiHFkQjQLNDA95BC
hNr9no538syTzRRF8x9FXn4=
-----END PRIVATE KEY-----
</key>
<tls-crypt>
#
# 2048 bit OpenVPN static key
#
-----BEGIN OpenVPN Static key V1-----
ca44162fccfbd6ab4a2c2a2e1c712683
45f367c91aa9d99e95c0c6a0aa17b7d5
954a923cf4c9163ae58330b5aae3896a
a58089d30bef059d5c7ac94b1555d11f
acacf1a8cdb75de9a379662383406ad4
2d5be83fb5189a96269ee61f2a818184
25a50fefaefdda2319285dc0181fbde0
4d42671715856c205b66e127469bde73
dbcb527b70fa7ae0e0b4340d46df9572
0f5117c5969a531f71d7544613762b9a
f3b186c3358c7b7fa9c181afb339d9eb
9c4b4f25e48daecf565c778f7adaca99
c3b06d80cac3f07067127ec8987b0edf
92e19c8ef5a018823913312f5713709b
12a0d795ccbda3d137597b9a353592ca
6300bc70ac6905a9c796fbf1a1976eed
-----END OpenVPN Static key V1-----
</tls-crypt>
#!/bin/bash
#
# https://github.com/Nyr/openvpn-install
#
# Copyright (c) 2013 Nyr. Released under the MIT License.
# Detect Debian users running the script with "sh" instead of bash
if readlink /proc/$$/exe | grep -q "dash"; then
echo 'This installer needs to be run with "bash", not "sh".'
exit
fi
# Discard stdin. Needed when running from an one-liner which includes a newline
read -N 999999 -t 0.001
# Detect OpenVZ 6
if [[ $(uname -r | cut -d "." -f 1) -eq 2 ]]; then
echo "The system is running an old kernel, which is incompatible with this installer."
exit
fi
# Detect OS
# $os_version variables aren't always in use, but are kept here for convenience
if grep -qs "ubuntu" /etc/os-release; then
os="ubuntu"
os_version=$(grep 'VERSION_ID' /etc/os-release | cut -d '"' -f 2 | tr -d '.')
group_name="nogroup"
elif [[ -e /etc/debian_version ]]; then
os="debian"
os_version=$(grep -oE '[0-9]+' /etc/debian_version | head -1)
group_name="nogroup"
elif [[ -e /etc/almalinux-release || -e /etc/rocky-release || -e /etc/centos-release ]]; then
os="centos"
os_version=$(grep -shoE '[0-9]+' /etc/almalinux-release /etc/rocky-release /etc/centos-release | head -1)
group_name="nobody"
elif [[ -e /etc/fedora-release ]]; then
os="fedora"
os_version=$(grep -oE '[0-9]+' /etc/fedora-release | head -1)
group_name="nobody"
else
echo "This installer seems to be running on an unsupported distribution.
Supported distros are Ubuntu, Debian, AlmaLinux, Rocky Linux, CentOS and Fedora."
exit
fi
if [[ "$os" == "ubuntu" && "$os_version" -lt 1804 ]]; then
echo "Ubuntu 18.04 or higher is required to use this installer.
This version of Ubuntu is too old and unsupported."
exit
fi
if [[ "$os" == "debian" && "$os_version" -lt 9 ]]; then
echo "Debian 9 or higher is required to use this installer.
This version of Debian is too old and unsupported."
exit
fi
if [[ "$os" == "centos" && "$os_version" -lt 7 ]]; then
echo "CentOS 7 or higher is required to use this installer.
This version of CentOS is too old and unsupported."
exit
fi
# Detect environments where $PATH does not include the sbin directories
if ! grep -q sbin <<< "$PATH"; then
echo '$PATH does not include sbin. Try using "su -" instead of "su".'
exit
fi
if [[ "$EUID" -ne 0 ]]; then
echo "This installer needs to be run with superuser privileges."
exit
fi
if [[ ! -e /dev/net/tun ]] || ! ( exec 7<>/dev/net/tun ) 2>/dev/null; then
echo "The system does not have the TUN device available.
TUN needs to be enabled before running this installer."
exit
fi
new_client () {
# Generates the custom client.ovpn
{
cat /etc/openvpn/server/client-common.txt
echo "<ca>"
cat /etc/openvpn/server/easy-rsa/pki/ca.crt
echo "</ca>"
echo "<cert>"
sed -ne '/BEGIN CERTIFICATE/,$ p' /etc/openvpn/server/easy-rsa/pki/issued/"$client".crt
echo "</cert>"
echo "<key>"
cat /etc/openvpn/server/easy-rsa/pki/private/"$client".key
echo "</key>"
echo "<tls-crypt>"
sed -ne '/BEGIN OpenVPN Static key/,$ p' /etc/openvpn/server/tc.key
echo "</tls-crypt>"
} > ~/"$client".ovpn
}
if [[ ! -e /etc/openvpn/server/server.conf ]]; then
# Detect some Debian minimal setups where neither wget nor curl are installed
if ! hash wget 2>/dev/null && ! hash curl 2>/dev/null; then
echo "Wget is required to use this installer."
read -n1 -r -p "Press any key to install Wget and continue..."
apt-get update
apt-get install -y wget
fi
clear
echo 'Welcome to this OpenVPN road warrior installer!'
# If system has a single IPv4, it is selected automatically. Else, ask the user
if [[ $(ip -4 addr | grep inet | grep -vEc '127(\.[0-9]{1,3}){3}') -eq 1 ]]; then
ip=$(ip -4 addr | grep inet | grep -vE '127(\.[0-9]{1,3}){3}' | cut -d '/' -f 1 | grep -oE '[0-9]{1,3}(\.[0-9]{1,3}){3}')
else
number_of_ip=$(ip -4 addr | grep inet | grep -vEc '127(\.[0-9]{1,3}){3}')
echo
echo "Which IPv4 address should be used?"
ip -4 addr | grep inet | grep -vE '127(\.[0-9]{1,3}){3}' | cut -d '/' -f 1 | grep -oE '[0-9]{1,3}(\.[0-9]{1,3}){3}' | nl -s ') '
read -p "IPv4 address [1]: " ip_number
until [[ -z "$ip_number" || "$ip_number" =~ ^[0-9]+$ && "$ip_number" -le "$number_of_ip" ]]; do
echo "$ip_number: invalid selection."
read -p "IPv4 address [1]: " ip_number
done
[[ -z "$ip_number" ]] && ip_number="1"
ip=$(ip -4 addr | grep inet | grep -vE '127(\.[0-9]{1,3}){3}' | cut -d '/' -f 1 | grep -oE '[0-9]{1,3}(\.[0-9]{1,3}){3}' | sed -n "$ip_number"p)
fi
# If $ip is a private IP address, the server must be behind NAT
if echo "$ip" | grep -qE '^(10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.|192\.168)'; then
echo
echo "This server is behind NAT. What is the public IPv4 address or hostname?"
# Get public IP and sanitize with grep
get_public_ip=$(grep -m 1 -oE '^[0-9]{1,3}(\.[0-9]{1,3}){3}$' <<< "$(wget -T 10 -t 1 -4qO- "http://ip1.dynupdate.no-ip.com/" || curl -m 10 -4Ls "http://ip1.dynupdate.no-ip.com/")")
read -p "Public IPv4 address / hostname [$get_public_ip]: " public_ip
# If the checkip service is unavailable and user didn't provide input, ask again
until [[ -n "$get_public_ip" || -n "$public_ip" ]]; do
echo "Invalid input."
read -p "Public IPv4 address / hostname: " public_ip
done
[[ -z "$public_ip" ]] && public_ip="$get_public_ip"
fi
# If system has a single IPv6, it is selected automatically
if [[ $(ip -6 addr | grep -c 'inet6 [23]') -eq 1 ]]; then
ip6=$(ip -6 addr | grep 'inet6 [23]' | cut -d '/' -f 1 | grep -oE '([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}')
fi
# If system has multiple IPv6, ask the user to select one
if [[ $(ip -6 addr | grep -c 'inet6 [23]') -gt 1 ]]; then
number_of_ip6=$(ip -6 addr | grep -c 'inet6 [23]')
echo
echo "Which IPv6 address should be used?"
ip -6 addr | grep 'inet6 [23]' | cut -d '/' -f 1 | grep -oE '([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}' | nl -s ') '
read -p "IPv6 address [1]: " ip6_number
until [[ -z "$ip6_number" || "$ip6_number" =~ ^[0-9]+$ && "$ip6_number" -le "$number_of_ip6" ]]; do
echo "$ip6_number: invalid selection."
read -p "IPv6 address [1]: " ip6_number
done
[[ -z "$ip6_number" ]] && ip6_number="1"
ip6=$(ip -6 addr | grep 'inet6 [23]' | cut -d '/' -f 1 | grep -oE '([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}' | sed -n "$ip6_number"p)
fi
echo
echo "Which protocol should OpenVPN use?"
echo " 1) UDP (recommended)"
echo " 2) TCP"
read -p "Protocol [1]: " protocol
until [[ -z "$protocol" || "$protocol" =~ ^[12]$ ]]; do
echo "$protocol: invalid selection."
read -p "Protocol [1]: " protocol
done
case "$protocol" in
1|"")
protocol=udp
;;
2)
protocol=tcp
;;
esac
echo
echo "What port should OpenVPN listen to?"
read -p "Port [1194]: " port
until [[ -z "$port" || "$port" =~ ^[0-9]+$ && "$port" -le 65535 ]]; do
echo "$port: invalid port."
read -p "Port [1194]: " port
done
[[ -z "$port" ]] && port="1194"
echo
echo "Select a DNS server for the clients:"
echo " 1) Current system resolvers"
echo " 2) Google"
echo " 3) 1.1.1.1"
echo " 4) OpenDNS"
echo " 5) Quad9"
echo " 6) AdGuard"
read -p "DNS server [1]: " dns
until [[ -z "$dns" || "$dns" =~ ^[1-6]$ ]]; do
echo "$dns: invalid selection."
read -p "DNS server [1]: " dns
done
echo
echo "Enter a name for the first client:"
read -p "Name [client]: " unsanitized_client
# Allow a limited set of characters to avoid conflicts
client=$(sed 's/[^0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-]/_/g' <<< "$unsanitized_client")
[[ -z "$client" ]] && client="client"
echo
echo "OpenVPN installation is ready to begin."
# Install a firewall if firewalld or iptables are not already available
if ! systemctl is-active --quiet firewalld.service && ! hash iptables 2>/dev/null; then
if [[ "$os" == "centos" || "$os" == "fedora" ]]; then
firewall="firewalld"
# We don't want to silently enable firewalld, so we give a subtle warning
# If the user continues, firewalld will be installed and enabled during setup
echo "firewalld, which is required to manage routing tables, will also be installed."
elif [[ "$os" == "debian" || "$os" == "ubuntu" ]]; then
# iptables is way less invasive than firewalld so no warning is given
firewall="iptables"
fi
fi
read -n1 -r -p "Press any key to continue..."
# If running inside a container, disable LimitNPROC to prevent conflicts
if systemd-detect-virt -cq; then
mkdir /etc/systemd/system/openvpn-server@server.service.d/ 2>/dev/null
echo "[Service]
LimitNPROC=infinity" > /etc/systemd/system/openvpn-server@server.service.d/disable-limitnproc.conf
fi
if [[ "$os" = "debian" || "$os" = "ubuntu" ]]; then
apt-get update
apt-get install -y openvpn openssl ca-certificates $firewall
elif [[ "$os" = "centos" ]]; then
yum install -y epel-release
yum install -y openvpn openssl ca-certificates tar $firewall
else
# Else, OS must be Fedora
dnf install -y openvpn openssl ca-certificates tar $firewall
fi
# If firewalld was just installed, enable it
if [[ "$firewall" == "firewalld" ]]; then
systemctl enable --now firewalld.service
fi
# Get easy-rsa
easy_rsa_url='https://github.com/OpenVPN/easy-rsa/releases/download/v3.1.0/EasyRSA-3.1.0.tgz'
mkdir -p /etc/openvpn/server/easy-rsa/
{ wget -qO- "$easy_rsa_url" 2>/dev/null || curl -sL "$easy_rsa_url" ; } | tar xz -C /etc/openvpn/server/easy-rsa/ --strip-components 1
chown -R root:root /etc/openvpn/server/easy-rsa/
cd /etc/openvpn/server/easy-rsa/
# Create the PKI, set up the CA and the server and client certificates
./easyrsa init-pki
./easyrsa --batch build-ca nopass
EASYRSA_CERT_EXPIRE=3650 ./easyrsa build-server-full server nopass
EASYRSA_CERT_EXPIRE=3650 ./easyrsa build-client-full "$client" nopass
EASYRSA_CRL_DAYS=3650 ./easyrsa gen-crl
# Move the stuff we need
cp pki/ca.crt pki/private/ca.key pki/issued/server.crt pki/private/server.key pki/crl.pem /etc/openvpn/server
# CRL is read with each client connection, while OpenVPN is dropped to nobody
chown nobody:"$group_name" /etc/openvpn/server/crl.pem
# Without +x in the directory, OpenVPN can't run a stat() on the CRL file
chmod o+x /etc/openvpn/server/
# Generate key for tls-crypt
openvpn --genkey --secret /etc/openvpn/server/tc.key
# Create the DH parameters file using the predefined ffdhe2048 group
echo '-----BEGIN DH PARAMETERS-----
MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz
+8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a
87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7
YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi
7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD
ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg==
-----END DH PARAMETERS-----' > /etc/openvpn/server/dh.pem
# Generate server.conf
echo "local $ip
port $port
proto $protocol
dev tun
ca ca.crt
cert server.crt
key server.key
dh dh.pem
auth SHA512
tls-crypt tc.key
topology subnet
server 10.8.0.0 255.255.255.0" > /etc/openvpn/server/server.conf
# IPv6
if [[ -z "$ip6" ]]; then
echo 'push "redirect-gateway def1 bypass-dhcp"' >> /etc/openvpn/server/server.conf
else
echo 'server-ipv6 fddd:1194:1194:1194::/64' >> /etc/openvpn/server/server.conf
echo 'push "redirect-gateway def1 ipv6 bypass-dhcp"' >> /etc/openvpn/server/server.conf
fi
echo 'ifconfig-pool-persist ipp.txt' >> /etc/openvpn/server/server.conf
# DNS
case "$dns" in
1|"")
# Locate the proper resolv.conf
# Needed for systems running systemd-resolved
if grep '^nameserver' "/etc/resolv.conf" | grep -qv '127.0.0.53' ; then
resolv_conf="/etc/resolv.conf"
else
resolv_conf="/run/systemd/resolve/resolv.conf"
fi
# Obtain the resolvers from resolv.conf and use them for OpenVPN
grep -v '^#\|^;' "$resolv_conf" | grep '^nameserver' | grep -v '127.0.0.53' | grep -oE '[0-9]{1,3}(\.[0-9]{1,3}){3}' | while read line; do
echo "push \"dhcp-option DNS $line\"" >> /etc/openvpn/server/server.conf
done
;;
2)
echo 'push "dhcp-option DNS 8.8.8.8"' >> /etc/openvpn/server/server.conf
echo 'push "dhcp-option DNS 8.8.4.4"' >> /etc/openvpn/server/server.conf
;;
3)
echo 'push "dhcp-option DNS 1.1.1.1"' >> /etc/openvpn/server/server.conf
echo 'push "dhcp-option DNS 1.0.0.1"' >> /etc/openvpn/server/server.conf
;;
4)
echo 'push "dhcp-option DNS 208.67.222.222"' >> /etc/openvpn/server/server.conf
echo 'push "dhcp-option DNS 208.67.220.220"' >> /etc/openvpn/server/server.conf
;;
5)
echo 'push "dhcp-option DNS 9.9.9.9"' >> /etc/openvpn/server/server.conf
echo 'push "dhcp-option DNS 149.112.112.112"' >> /etc/openvpn/server/server.conf
;;
6)
echo 'push "dhcp-option DNS 94.140.14.14"' >> /etc/openvpn/server/server.conf
echo 'push "dhcp-option DNS 94.140.15.15"' >> /etc/openvpn/server/server.conf
;;
esac
echo "keepalive 10 120
cipher AES-256-CBC
user nobody
group $group_name
persist-key
persist-tun
verb 3
crl-verify crl.pem" >> /etc/openvpn/server/server.conf
if [[ "$protocol" = "udp" ]]; then
echo "explicit-exit-notify" >> /etc/openvpn/server/server.conf
fi
# Enable net.ipv4.ip_forward for the system
echo 'net.ipv4.ip_forward=1' > /etc/sysctl.d/99-openvpn-forward.conf
# Enable without waiting for a reboot or service restart
echo 1 > /proc/sys/net/ipv4/ip_forward
if [[ -n "$ip6" ]]; then
# Enable net.ipv6.conf.all.forwarding for the system
echo "net.ipv6.conf.all.forwarding=1" >> /etc/sysctl.d/99-openvpn-forward.conf
# Enable without waiting for a reboot or service restart
echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
fi
if systemctl is-active --quiet firewalld.service; then
# Using both permanent and not permanent rules to avoid a firewalld
# reload.
# We don't use --add-service=openvpn because that would only work with
# the default port and protocol.
firewall-cmd --add-port="$port"/"$protocol"
firewall-cmd --zone=trusted --add-source=10.8.0.0/24
firewall-cmd --permanent --add-port="$port"/"$protocol"
firewall-cmd --permanent --zone=trusted --add-source=10.8.0.0/24
# Set NAT for the VPN subnet
firewall-cmd --direct --add-rule ipv4 nat POSTROUTING 0 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to "$ip"
firewall-cmd --permanent --direct --add-rule ipv4 nat POSTROUTING 0 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to "$ip"
if [[ -n "$ip6" ]]; then
firewall-cmd --zone=trusted --add-source=fddd:1194:1194:1194::/64
firewall-cmd --permanent --zone=trusted --add-source=fddd:1194:1194:1194::/64
firewall-cmd --direct --add-rule ipv6 nat POSTROUTING 0 -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j SNAT --to "$ip6"
firewall-cmd --permanent --direct --add-rule ipv6 nat POSTROUTING 0 -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j SNAT --to "$ip6"
fi
else
# Create a service to set up persistent iptables rules
iptables_path=$(command -v iptables)
ip6tables_path=$(command -v ip6tables)
# nf_tables is not available as standard in OVZ kernels. So use iptables-legacy
# if we are in OVZ, with a nf_tables backend and iptables-legacy is available.
if [[ $(systemd-detect-virt) == "openvz" ]] && readlink -f "$(command -v iptables)" | grep -q "nft" && hash iptables-legacy 2>/dev/null; then
iptables_path=$(command -v iptables-legacy)
ip6tables_path=$(command -v ip6tables-legacy)
fi
echo "[Unit]
Before=network.target
[Service]
Type=oneshot
ExecStart=$iptables_path -t nat -A POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to $ip
ExecStart=$iptables_path -I INPUT -p $protocol --dport $port -j ACCEPT
ExecStart=$iptables_path -I FORWARD -s 10.8.0.0/24 -j ACCEPT
ExecStart=$iptables_path -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
ExecStop=$iptables_path -t nat -D POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to $ip
ExecStop=$iptables_path -D INPUT -p $protocol --dport $port -j ACCEPT
ExecStop=$iptables_path -D FORWARD -s 10.8.0.0/24 -j ACCEPT
ExecStop=$iptables_path -D FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT" > /etc/systemd/system/openvpn-iptables.service
if [[ -n "$ip6" ]]; then
echo "ExecStart=$ip6tables_path -t nat -A POSTROUTING -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j SNAT --to $ip6
ExecStart=$ip6tables_path -I FORWARD -s fddd:1194:1194:1194::/64 -j ACCEPT
ExecStart=$ip6tables_path -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
ExecStop=$ip6tables_path -t nat -D POSTROUTING -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j SNAT --to $ip6
ExecStop=$ip6tables_path -D FORWARD -s fddd:1194:1194:1194::/64 -j ACCEPT
ExecStop=$ip6tables_path -D FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT" >> /etc/systemd/system/openvpn-iptables.service
fi
echo "RemainAfterExit=yes
[Install]
WantedBy=multi-user.target" >> /etc/systemd/system/openvpn-iptables.service
systemctl enable --now openvpn-iptables.service
fi
# If SELinux is enabled and a custom port was selected, we need this
if sestatus 2>/dev/null | grep "Current mode" | grep -q "enforcing" && [[ "$port" != 1194 ]]; then
# Install semanage if not already present
if ! hash semanage 2>/dev/null; then
if [[ "$os_version" -eq 7 ]]; then
# Centos 7
yum install -y policycoreutils-python
else
# CentOS 8 or Fedora
dnf install -y policycoreutils-python-utils
fi
fi
semanage port -a -t openvpn_port_t -p "$protocol" "$port"
fi
# If the server is behind NAT, use the correct IP address
[[ -n "$public_ip" ]] && ip="$public_ip"
# client-common.txt is created so we have a template to add further users later
echo "client
dev tun
proto $protocol
remote $ip $port
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
auth SHA512
cipher AES-256-CBC
ignore-unknown-option block-outside-dns
block-outside-dns
verb 3" > /etc/openvpn/server/client-common.txt
# Enable and start the OpenVPN service
systemctl enable --now openvpn-server@server.service
# Generates the custom client.ovpn
new_client
echo
echo "Finished!"
echo
echo "The client configuration is available in:" ~/"$client.ovpn"
echo "New clients can be added by running this script again."
else
clear
echo "OpenVPN is already installed."
echo
echo "Select an option:"
echo " 1) Add a new client"
echo " 2) Revoke an existing client"
echo " 3) Remove OpenVPN"
echo " 4) Exit"
read -p "Option: " option
until [[ "$option" =~ ^[1-4]$ ]]; do
echo "$option: invalid selection."
read -p "Option: " option
done
case "$option" in
1)
echo
echo "Provide a name for the client:"
read -p "Name: " unsanitized_client
client=$(sed 's/[^0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-]/_/g' <<< "$unsanitized_client")
while [[ -z "$client" || -e /etc/openvpn/server/easy-rsa/pki/issued/"$client".crt ]]; do
echo "$client: invalid name."
read -p "Name: " unsanitized_client
client=$(sed 's/[^0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-]/_/g' <<< "$unsanitized_client")
done
cd /etc/openvpn/server/easy-rsa/
EASYRSA_CERT_EXPIRE=3650 ./easyrsa build-client-full "$client" nopass
# Generates the custom client.ovpn
new_client
echo
echo "$client added. Configuration available in:" ~/"$client.ovpn"
exit
;;
2)
# This option could be documented a bit better and maybe even be simplified
# ...but what can I say, I want some sleep too
number_of_clients=$(tail -n +2 /etc/openvpn/server/easy-rsa/pki/index.txt | grep -c "^V")
if [[ "$number_of_clients" = 0 ]]; then
echo
echo "There are no existing clients!"
exit
fi
echo
echo "Select the client to revoke:"
tail -n +2 /etc/openvpn/server/easy-rsa/pki/index.txt | grep "^V" | cut -d '=' -f 2 | nl -s ') '
read -p "Client: " client_number
until [[ "$client_number" =~ ^[0-9]+$ && "$client_number" -le "$number_of_clients" ]]; do
echo "$client_number: invalid selection."
read -p "Client: " client_number
done
client=$(tail -n +2 /etc/openvpn/server/easy-rsa/pki/index.txt | grep "^V" | cut -d '=' -f 2 | sed -n "$client_number"p)
echo
read -p "Confirm $client revocation? [y/N]: " revoke
until [[ "$revoke" =~ ^[yYnN]*$ ]]; do
echo "$revoke: invalid selection."
read -p "Confirm $client revocation? [y/N]: " revoke
done
if [[ "$revoke" =~ ^[yY]$ ]]; then
cd /etc/openvpn/server/easy-rsa/
./easyrsa --batch revoke "$client"
EASYRSA_CRL_DAYS=3650 ./easyrsa gen-crl
rm -f /etc/openvpn/server/crl.pem
cp /etc/openvpn/server/easy-rsa/pki/crl.pem /etc/openvpn/server/crl.pem
# CRL is read with each client connection, when OpenVPN is dropped to nobody
chown nobody:"$group_name" /etc/openvpn/server/crl.pem
echo
echo "$client revoked!"
else
echo
echo "$client revocation aborted!"
fi
exit
;;
3)
echo
read -p "Confirm OpenVPN removal? [y/N]: " remove
until [[ "$remove" =~ ^[yYnN]*$ ]]; do
echo "$remove: invalid selection."
read -p "Confirm OpenVPN removal? [y/N]: " remove
done
if [[ "$remove" =~ ^[yY]$ ]]; then
port=$(grep '^port ' /etc/openvpn/server/server.conf | cut -d " " -f 2)
protocol=$(grep '^proto ' /etc/openvpn/server/server.conf | cut -d " " -f 2)
if systemctl is-active --quiet firewalld.service; then
ip=$(firewall-cmd --direct --get-rules ipv4 nat POSTROUTING | grep '\-s 10.8.0.0/24 '"'"'!'"'"' -d 10.8.0.0/24' | grep -oE '[^ ]+$')
# Using both permanent and not permanent rules to avoid a firewalld reload.
firewall-cmd --remove-port="$port"/"$protocol"
firewall-cmd --zone=trusted --remove-source=10.8.0.0/24
firewall-cmd --permanent --remove-port="$port"/"$protocol"
firewall-cmd --permanent --zone=trusted --remove-source=10.8.0.0/24
firewall-cmd --direct --remove-rule ipv4 nat POSTROUTING 0 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to "$ip"
firewall-cmd --permanent --direct --remove-rule ipv4 nat POSTROUTING 0 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to "$ip"
if grep -qs "server-ipv6" /etc/openvpn/server/server.conf; then
ip6=$(firewall-cmd --direct --get-rules ipv6 nat POSTROUTING | grep '\-s fddd:1194:1194:1194::/64 '"'"'!'"'"' -d fddd:1194:1194:1194::/64' | grep -oE '[^ ]+$')
firewall-cmd --zone=trusted --remove-source=fddd:1194:1194:1194::/64
firewall-cmd --permanent --zone=trusted --remove-source=fddd:1194:1194:1194::/64
firewall-cmd --direct --remove-rule ipv6 nat POSTROUTING 0 -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j SNAT --to "$ip6"
firewall-cmd --permanent --direct --remove-rule ipv6 nat POSTROUTING 0 -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j SNAT --to "$ip6"
fi
else
systemctl disable --now openvpn-iptables.service
rm -f /etc/systemd/system/openvpn-iptables.service
fi
if sestatus 2>/dev/null | grep "Current mode" | grep -q "enforcing" && [[ "$port" != 1194 ]]; then
semanage port -d -t openvpn_port_t -p "$protocol" "$port"
fi
systemctl disable --now openvpn-server@server.service
rm -f /etc/systemd/system/openvpn-server@server.service.d/disable-limitnproc.conf
rm -f /etc/sysctl.d/99-openvpn-forward.conf
if [[ "$os" = "debian" || "$os" = "ubuntu" ]]; then
rm -rf /etc/openvpn/server
apt-get remove --purge -y openvpn
else
# Else, OS must be CentOS or Fedora
yum remove -y openvpn
rm -rf /etc/openvpn/server
fi
echo
echo "OpenVPN removed!"
else
echo
echo "OpenVPN removal aborted!"
fi
exit
;;
4)
exit
;;
esac
fi

-- List Users SELECT * FROM pg_catalog.pg_user ORDER BY 1; SELECT * from information_schema.table_privileges WHERE grantee = 'milksub-charger' LIMIT 5;

SELECT usename AS role_name, CASE WHEN usesuper AND usecreatedb THEN CAST('superuser, create database' AS pg_catalog.text) WHEN usesuper THEN CAST('superuser' AS pg_catalog.text) WHEN usecreatedb THEN CAST('create database' AS pg_catalog.text) ELSE CAST('' AS pg_catalog.text) END role_attributes FROM pg_catalog.pg_user ORDER BY role_name desc;

-- show user permissions SELECT table_catalog, table_schema, table_name, privilege_type FROM information_schema.table_privileges WHERE grantee = 'milksub-subscriber'

-- show users in DATABASE SELECT grantee ,table_catalog ,table_schema ,table_name ,string_agg(privilege_type, ', ' ORDER BY privilege_type) AS privileges FROM information_schema.role_table_grants WHERE grantee != 'postgres' GROUP BY grantee, table_catalog, table_schema, table_name;

-- Create User CREATE USER "milkguard-api" WITH PASSWORD 'wLkEQnulpSN8sH2o9t6kkQ6jk5F'; GRANT USAGE ON SCHEMA public TO "milkguard-api"; GRANT SELECT, INSERT, UPDATE ON ALL TABLES IN SCHEMA public TO "milkguard-api"; GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO "milkguard-api";

-- bypass alter table problem CREATE ROLE aleksandrp LOGIN INHERIT; CREATE ROLE administrator NOINHERIT; GRANT administrator TO aleksandrp;

-- Grant permissions GRANT INSERT ON tags TO "milksub-subscriber";

-- Get Databases sizes SELECT pg_database.datname as "milkguard", pg_database_size(pg_database.datname)/1024/1024 AS size_in_mb FROM pg_database ORDER by size_in_mb DESC; -- Get Table sizes select table_name, pg_size_pretty( pg_relation_size(quote_ident(table_name)) ) from information_schema.tables where table_schema = 'public' order by pg_relation_size(quote_ident(table_name)) desc

User Management

# User Create
    -   CREATE USER username WITH PASSWORD '12345';

# Grant USAGE to user
    -    GRANT USAGE ON SCHEMA milkpayui-tools to milkpayui-back-fpm;

# User Grant Permissions USER
    -   GRANT SELECT,UPDATE,DELETE,REFERENCES ON database_name.* TO 'username'@'%';
    -   GRANT SELECT, INSERT, UPDATE ,DELETE, REFERENCES ON ALL TABLES IN SCHEMA schema_name TO username;

# Group grant Permissions GROUP
    -    GRANT SELECT ON database_name.* TO GROUP data_viewers;
    -    GRANT SELECT ON ALL TABLES IN SCHEMA "milkpayui-tools" TO GROUP application_read;
         -    this will grant select on all tables, will presist after table is re-created.

------------------------------------------------------------------------------------

# User Group ADD / Assign / Alter
    -   CREATE GROUP group_name

    -   ALTER GROUP group_name ADD USER username   
    -   ALTER GROUP group_name DROP USER username    

    -   GRANT USAGE on schema schema_name to group group_name;

------------------------------------------------------------------------------------

# User Update Password
    -   alter user "user_name" password '<<<New Password Here>>>';

# User Delete
    -   DELETE FROM mysql.user WHERE user = 'username';

# User Revoke Permissions
    -   REVOKE ALL ON DATABASE database_name FROM username;
    -   REVOKE ALL ON SCHEMA schema_name FROM username; 

default privilages override

# override privilages of a user & then run permission command again
    -   alter default privileges for user {{ USER }} grant select on tables to group {{ GROUP NAME WHERE USER IS}};
        -   this will grant select on all tables {{ USER }} creates to the group specified.
    -   GRANT SELECT ON TABLES TO GROUP application_read;
    
    -   Revoke:
        -   ALTER DEFAULT PRIVILEGES for user {{ USER }} in schema {{ SCHEMA }} REVOKE ALL on tables FROM group {{ GROUP }};

# verify
    -   select pg_get_userbyid(d.defacluser) as user, 
        n.nspname as schema, 
        case d.defaclobjtype when 'r' then 'tables' when 'f' then 'functions' end 
        as object_type, 
        array_to_string(d.defaclacl, ' + ')  as default_privileges 
        from pg_catalog.pg_default_acl d 
        left join pg_catalog.pg_namespace n on n.oid = d.defaclnamespace;

#################################################################################### ##################################### Information ################################## #################################################################################### # list namespaces / schemas - select * from pg_namespace; - SELECT * FROM pg_group;

# list schema owners
    - select nspname as schema, usename as owner from pg_namespace, pg_user 

# list users in groups (with Permissions)
    - SELECT 
        pg_group.groname
        ,pg_group.grosysid
        ,pg_user.*
    FROM pg_group, pg_user 
    WHERE pg_user.usesysid = ANY(pg_group.grolist) 
    ORDER BY 1, 2;

# list user permissions per table in schema
    - WITH 
        usrs as (SELECT * FROM pg_user),
        objs as (
        SELECT 
            schemaname, 't' AS obj_type,
            tablename AS objectname,
            schemaname + '.' + tablename AS fullobj
        FROM pg_tables
        WHERE schemaname not in ('pg_internal')
        UNION
        SELECT 
            schemaname, 'v' AS obj_type, 
            viewname AS objectname, 
            schemaname + '.' + viewname AS fullobj 
        FROM pg_views
        WHERE schemaname NOT IN ('pg_internal')
      ),
      query as (
      SELECT 
          schemaname,
          objectname,
          usename,
          HAS_TABLE_PRIVILEGE(usrs.usename, fullobj, 'select') AS sel,
          HAS_TABLE_PRIVILEGE(usrs.usename, fullobj, 'insert') AS ins,
          HAS_TABLE_PRIVILEGE(usrs.usename, fullobj, 'update') AS upd,
          HAS_TABLE_PRIVILEGE(usrs.usename, fullobj, 'delete') AS del,
          HAS_TABLE_PRIVILEGE(usrs.usename, fullobj, 'references') AS ref
        FROM objs, usrs
        ORDER BY fullobj
      )
      SELECT * FROM query
        WHERE (
        sel = TRUE 
        OR ins = TRUE 
        OR upd = TRUE 
        OR del = TRUE 
        OR ref = TRUE
        ) 
      AND schemaname='milkpayui-tools'
      --   AND usename = '[optional username]';

Rsync through bastion

`rsync -azP -e "ssh {{ Bastion Server }} ssh" ~/Downloads/script  {{ USER }}@{{ PASSWORD }}:/tmp/`
                                                Local Directory                             Remote Directory                                                  

Tunnel

- ssh -N -L <LOCAL_PORT>:<REMOTE_SERVER>:<REMOTE_SERVER_PORT> <USER>@<BASTION SERVER>
  - ssh -N -L 11001:b-1.brandvno-staging-kafka.strn7p.c2.kafka.us-east-1.amazonaws.com:11001 oxioeng.com
  - ssh -L 3307:prod-btg-mysql-rds.cohoevkb0ihs.us-east-1.rds.amazonaws.com:3306 -i "jumpbox4btg.pem" ubuntu@ec2-54-226-83-241.compute-1.amazonaws.com -N

SSM Installation

SSM Config "~ /.ssh/config"

host i-* mi-* ProxyCommand sh -c "aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"

SSM Connection

aws ssm start-session --target 'i-0e0159c304fd4b95b'

SSM RDS Tunnel

Database Connection Steps

  1. Open Terminal 1
  • aws ssm start-session --target 'i-0e0159c304fd4b95b'
  • sudo yum install -y socat
  • sudo socat TCP-LISTEN:3306,reuseaddr,fork TCP4:staging-btg-rds.cohoevkb0ihs.us-east-1.rds.amazonaws.com:3306
    • this will create tunnel with DB
  1. Open Terminal 2
  • aws ssm start-session --target i-0e0159c304fd4b95b --document-name AWS-StartPortForwardingSession --parameters '{"portNumber":["3306"], "localPortNumber":["3306"]}'
    • This will open tunnel with Instance.
  1. Connect to Database locally
  • host: localhost
  • port: 3306
  • user: admin
  • password: btg123456

Note: There is 2 tunnels. one is for EC2 > RDS and second one is LOCAL > EC2

Guide: https://www.element7.io/2021/01/aws-ssm-session-manager-port-forwarding-to-rds-without-ssh/

Tunnel for DB

  • aws ssm start-session --target 'i-08f8a3405c1a04c61' --profile milkpay-dev

  • sudo socat TCP-LISTEN:5432,reuseaddr,fork TCP4:swarm-database-pgsql-0-dev.cadmwqe2fb6k.us-east-1.rds.amazonaws.com:5432

  • aws ssm start-session --target i-08f8a3405c1a04c61 --document-name AWS-StartPortForwardingSession --parameters '{"portNumber":["5432"], "localPortNumber":["5432"]}' --profile milkpay-dev

SSH over SSM

$ export AWS_PROFILE=profile_name
$ aws ssm start-session --target i-06exxxa5fxxxc03xx

# edit ~/.ssh/config, add the following lines:

host i-* mi-* 10.
User ec2-user
ProxyCommand sh -c "export AWS_PROFILE=<name>; aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"
IdentityFile ~/.ssh/aws-key.pem

$ $ ssh-add ~/.ssh/aws-ec2-private-key.pem
$ ssh ec2-user@i-002d7e70587b0c355
or
$ ssh -i ~/.ssh/aws-ec2-private-key.pem ec2-user@10.10.10.101
or simply
$ ssh i-002d7e70587b0c355

Monitor Traffic

- tcpdump -i any -A -vv -s 0 | egrep -e "GET" -e "POST" -e "Host:"
- tcpdump -i any -A -vv -s 0 |  grep -e "Host:" 

ForEach Loop (Pay attention how we take index from list and use eacch value.)

for_each                    = toset(data.aws_subnets.private.ids)
subnet_id                   = each.value
tags                        = merge(var.tags, {Name = "${var.name}-${index(tolist(toset(data.aws_subnets.private.ids)),each.value)}-${var.environment}"})
/* INSTRUCTIONS
dockersock allows traefik to run on worker nodes. By default traefik needs to run on manager nodes.
dockersock uses socat to establish a secure communication with docker.sock API on the manager nodes.
--providers.docker.endpoint=tcp://dockersock:2375
tells the container to communicate with the service which has access to the docker API.
This setup includes basic authentication and allows for the usage of
*/
version: "3.7"
services:
# ### INSTRUCTIONS ###
# Create Swarm network before deployment
# docker network create --driver=overlay proxy
# Create Copy of this file on the server in /tmp/docker-compose.yml
# sudo docker stack deploy -c docker-compose.yml traefik
traefik:
image: traefik:2.7
logging:
driver: awslogs
options:
awslogs-region: "us-east-1"
awslogs-group: "traefik-logs"
awslogs-create-group: "true"
awslogs-stream: "traefik"
networks:
- proxy
- web
command:
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
- --providers.docker.exposedbydefault=false
# Swarm
- --providers.docker.swarmmode=true
# Enables web UI and tells Traefik to listen to docker
- --providers.docker
- --api
# healthcheck
- --entrypoints.ping.address=:8080
- --ping.entrypoint=ping
# Logging
- --log.level=error # DEBUG, ERROR, INFO???
- --providers.docker.endpoint=tcp://dockersock:2375
ports:
- target: 80
published: 80
mode: host
- target: 8080
published: 8080
mode: host
- target: 443
published: 443
mode: host
# volumes:
# # So that Traefik can listen to the Docker events
# - /var/run/docker.sock:/var/run/docker.sock:ro
deploy:
mode: global
labels:
traefik.enable: "true"
traefik.docker.network: traefik_proxy
# Dashboard
traefik.http.routers.web.rule: "Host(`traefik.milkpay-dev.systems`)"
traefik.http.routers.web.service: api@internal
# traefik.http.routers.traefik.tls.certresolver: leresolver
# traefik.http.routers.traefik.entrypoints: web
traefik.http.routers.web.middlewares: auth-traefik
# Swarm Mode
traefik.http.services.web.loadbalancer.server.port: 80
# Basic Auth
traefik.http.middlewares.auth-traefik.basicauth.users: "user:$$apr1$$t0FVNENA$$iznG3A5w.mo/ff/WeFzQp/"
# Global http to https redirect
traefik.http.routers.http-catchall.rule: "hostregexp(`{host:.+}`)"
traefik.http.routers.http-catchall.entrypoints: web
traefik.http.routers.http-catchall.middlewares: redirect-to-https
# Middleware redirect
traefik.http.middlewares.redirect-to-https.redirectscheme.scheme: https
traefik.frontend.passHostHeader: 'true'
placement:
constraints: ["node.role==worker"]
resources:
limits:
memory: 1g
reservations:
memory: 500M
dockersock:
image: tecnativa/docker-socket-proxy
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
ports:
- '2375:2375'
logging:
driver: awslogs
options:
awslogs-region: "us-east-1"
awslogs-group: "traefik-logs"
awslogs-create-group: "true"
awslogs-stream: "docker-sock"
environment:
BUILD: 1
COMMIT: 1
CONFIGS: 1
CONTAINERS: 1
DISTRIBUTION: 1
EXEC: 1
IMAGES: 1
INFO: 1
NETWORKS: 1
NODES: 1
PLUGINS: 1
SERVICES: 1
SESSION: 1
SWARM: 1
SYSTEM: 1
TASKS: 1
VOLUMES: 1
networks:
- proxy
deploy:
mode: global
update_config:
order: start-first
placement:
constraints: [node.role == manager]
resources:
limits:
cpus: '2'
memory: 1g
reservations:
cpus: '1'
memory: 500M
whoami:
image: "traefik/whoami"
deploy:
labels:
traefik.enable: "true"
traefik.http.routers.whoami.rule: "Host(`whoami.milkpay-dev.systems`)"
traefik.http.routers.whoami.entrypoints: web
traefik.http.routers.whoami.service: whoami
traefik.http.services.whoami.loadbalancer.server.scheme: http
traefik.http.services.whoami.loadbalancer.server.port: 80
placement:
constraints: [node.role == worker]
resources:
limits:
cpus: '0.25'
memory: 100M
reservations:
cpus: '0.50'
memory: 50M
networks:
proxy:
driver: overlay
web:
driver: overlay
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment