- Debian 12.13 (Bookworm)
- VPS with Public IPv4 Address available
- IPv6 Address is selectively
- Running Apache2 service for obfuscating
Check IP address
ip aOutput be like:
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host noprefixroute
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:0c:29:8d:49:9f brd ff:ff:ff:ff:ff:ff
inet XXX.XXX.XXX.XXX/24 brd 139.162.71.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 2400:8902:0:1::/64 scope global dynamic mngtmpaddr
valid_lft 5349sec preferred_lft 1749sec
inet6 fe80::XXXX:XXXX:XXXX:XXXX/64 scope link
valid_lft forever preferred_lft forever
Copy inet and inet6 WAN IPv4/IPv6 address.
apt install ufw sslh openvpn easy-rsa -y# Switch to OpenVPN folder
cd /etc/openvpn/
# Create PKI folder
mkdir -p easy-rsa
cd easy-rsa/
# Create symbolic link to easyrsa
ln -s /usr/share/easy-rsa/easyrsa ./easyrsa
# Init PKI
./easyrsa init-pki
# Create certificates
./easyrsa build-ca nopass
# Create server certificates
./easyrsa build-server-full server nopass
# Diffie-Hellman key exchange
./easyrsa gen-dh
# Create TLS-Crypt authentication key
openvpn --genkey secret /etc/openvpn/server/ta.key# Switch folder
cd /etc/openvpn/easy-rsa/
# copy
cp pki/ca.crt /etc/openvpn/server/
cp pki/issued/server.crt /etc/openvpn/server/
cp pki/private/server.key /etc/openvpn/server/
cp pki/dh.pem /etc/openvpn/server/# Switch folder
cd /etc/openvpn/server/
# create config file
touch server.conf
# Edit
vim server.confUse following configuration:
# Server listening
local 127.0.0.1
# Port config
port 1194
# Using TCP
proto tcp
# OSI Layer 3, Virtual network interface
# IPv6 enable by default after version 2.5
dev tun
# Maximum Transmission Unit, default 1500
# In case of packet too big issue, suggestion is 1400
tun-mtu 1400
# Maximum Segment Size
mssfix 1360
# Certificate
ca /etc/openvpn/server/ca.crt
cert /etc/openvpn/server/server.crt
key /etc/openvpn/server/server.key
dh /etc/openvpn/server/dh.pem
tls-crypt /etc/openvpn/server/ta.key 0
# Auth
cipher AES-256-GCM
auth SHA256
# Permission protect
user nobody
group nogroup
persist-key
persist-tun
# VPN Subnetwork IPv4
server 10.8.0.0 255.255.255.0
# Keep alive
keepalive 10 120
# Set server side as gateway
push "redirect-gateway def1 bypass-dhcp"
# DNS config, Cloudflare DNS IPv4
push "dhcp-option DNS 1.1.1.1"
push "dhcp-option DNS 1.0.0.1"
# Client-Specific Rules
client-config-dir /etc/openvpn/ccd
# Disable compress function
compress migrate
comp-noadapt
# Log
status /var/log/openvpn/status.log
log /var/log/openvpn/openvpn.log
# Debugging, rollback to 1 after test
verb 4
mkdir -p /var/log/openvpnvim /etc/sysctl.confEnable IP Forward
# IPv4
net.ipv4.ip_forward=1
# IPv6
net.ipv6.conf.all.forwarding=1
# Active configuration
sysctl -pDisable UFW when change configuration
# Disable when change configuration
ufw disableCheck Network interface card.
Network interface card usually named eth0.
ip route | grep default | awk '{print $5}'Editing UFW default rules.
vim /etc/ufw/before.rulesAllow NAT for OpenVPN at eth0.
Following should place before *filter.
*nat
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A PREROUTING -p tcp --dport 8080 -j REDIRECT --to-port 1194
-A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
COMMIT
For IPv6. Following should place before *filter.
vim /etc/ufw/before6.rules# If your WAN IPv6 is 2400:8902:0:1::/64, plus one at first group.
*nat
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -s 2401:8902:0:1::/64 -o eth0 -j MASQUERADE
COMMIT
Allow UFW forward
vim /etc/default/ufwFind DEFAULT_FORWARD_POLICY, modify DROP to ACCEPT
DEFAULT_FORWARD_POLICY="ACCEPT"
Rule Configuration
# Default deny all connect
ufw default deny
# Allow SSH connect
ufw allow 22/tcp comment 'SSH'
# Allow 443/tcp for SSLH
ufw allow 443/tcp comment 'SSLH'
# Allow 8080 for OpenVPN
ufw allow 8080/tcp comment 'OpenVPN'Active UFW.
ufw disable && ufw enable
# Enable when booting
systemctl enable ufw# Stop Apache server
systemctl stop apache2
# Editing port configuration
vim /etc/apache2/ports.conf# Disable HTTP
# Listen 80
# HTTPS using 8090
<IfModule ssl_module>
Listen 8090
</IfModule>
<IfModule mod_gnutls.c>
Listen 8090
</IfModule>
# Editing site configuration
vim /etc/apache2/sites-available/000-default.confChange HTTPS from port 443 to 8090:
# IP address request
<VirtualHost _default_:8090>
...(Ommit)...
</VirtualHost>
# ServerName based request
<VirtualHost *:8090>
...(Ommit)...
</VirtualHost>
# Restart apache2
systemctl restart apache2vim /etc/default/sslh# Enable SSLH service
RUN=yes
# Package sorting mechanism
DAEMON_OPTS="--user sslh --listen 0.0.0.0:443 --listen :::443 --tls 127.0.0.1:8090 --openvpn 127.0.0.1:1194 --http 127.0.0.1:1080 --pidfile /var/run/sslh/sslh.pid"
# --listen 0.0.0.0:443 > IPv4 listening
# --listen :::443 > IPv6 listening
# --tls 127.0.0.1:8090 > HTTPS
# --openvpn 127.0.0.1:1194 > OpenVPN
# --http 127.0.0.1:1080 > Shadowsocks
# Please follow the correct combination, HTTPS(TLS) > OpenVPN > HTTP.
# Otherwise, the sorting mechanism will not function properly.
Restart and Check SSLH Status
systemctl restart sslh
systemctl status sslh# Restart OpenVPN
systemctl enable --now openvpn-server@server
systemctl status openvpn-server@server
# Check port status
ss -tlnp | grep -E '443|1080|1194|8080|8090'# Create user file folder
mkdir -p /home/openvpn_user
# Switch folder
cd /home/openvpn_user
# Create script
touch opv_adduser.sh
# Editing script
vim opv_adduser.shPasting following script:
#!/bin/bash
# Server IPv4
# Your server address
SERVER_IP="XXX.XXX.XXX.XXX"
# Server Port
SERVER_PORT="443"
# Asking client
CLIENT=$1
# Need client name
if [ -z "$CLIENT" ]; then
echo "Please setting $0 <client-name>"
exit 1
fi
# Check user name if exists
cd /etc/openvpn/easy-rsa
if [ -f "pki/issued/${CLIENT}.crt" ]; then
echo "Error: Client '$CLIENT' already exists"
exit 1
fi
# Create User certificates
./easyrsa build-client-full "$CLIENT" nopass
# Certificates payload
CA=$(cat pki/ca.crt)
CERT=$(openssl x509 -in "pki/issued/${CLIENT}.crt")
KEY=$(cat "pki/private/${CLIENT}.key")
TLS=$(cat /etc/openvpn/server/ta.key)
# Output opvn file
mkdir -p /home/OpenVPN_User
cat > "/home/OpenVPN_User/${CLIENT}.ovpn" <<EOF
client
dev tun
proto tcp
remote $SERVER_IP $SERVER_PORT
resolv-retry infinite
nobind
persist-key
persist-tun
tun-mtu 1400
mssfix 1360
cipher AES-256-GCM
auth SHA256
remote-cert-tls server
verb 2
<ca>
$CA
</ca>
<cert>
$CERT
</cert>
<key>
$KEY
</key>
<tls-crypt>
$TLS
</tls-crypt>
EOF
echo "openvpn configuration file at: /home/OpenVPN_User/${CLIENT}.ovpn"Executable the script
chmod +x opv_adduser.shUsing the script
bash opv_adduser.sh <user name>
Selectively IPv6.
# Create script
touch opv_addccd.sh
# Editing script
vim opv_addccd.shPasting following script:
#!/bin/bash
# Asking client
CLIENT=$1
# Need client name
if [ -z "$CLIENT" ]; then
echo "Please setting $0 <client-name>"
exit 1
fi
# Check user name if exists
cd /etc/openvpn/easy-rsa
if [ ! -f "pki/issued/${CLIENT}.crt" ]; then
echo "Error: Client '${CLIENT}' does not exist, create account first"
exit 1
fi
# Check CCD
if [ -f "/etc/openvpn/ccd/${CLIENT}" ]; then
echo "CCD for '${CLIENT}' already exists"
exit 1
fi
# Create User CCD folder
mkdir -p /etc/openvpn/ccd/
# 1. VPN Server IPv6
# If your WAN IPv6 is 2400:8902:0:1::/64, plus one at first group
# 2. Psuh Subnetwork IPv6 to client.
# If your WAN IPv6 is 2400:8902:0:1::/64, plus one at first group.
# 3. Push IPv6 route. This part don't need plus one at first group.
# 4. Push DNS config, Cloudflare DNS IPv6
cat > "/etc/openvpn/ccd/${CLIENT}" <<EOF
ifconfig-ipv6-push 2401:8902:0:1::2/64 2401:8902:0:1::1
push "route-ipv6 2401:8902:0:1::/64"
push "route-ipv6 2400::/3"
push "dhcp-option DNS6 2606:4700:4700::1111"
push "dhcp-option DNS6 2606:4700:4700::1001"
EOF
# Print result
echo "Client-specific configuration create at: /etc/openvpn/ccd/${CLIENT}"Executable the script
chmod +x opv_addccd.shUsing the script
bash opv_addccd.sh <user name>