Dit artikel gaat over het opzetten van een moderne mailserver.
Postfix + Dovecot. SPF + DKIM + rDNS. Met IPv6.
Met TSL-encryptie. Ondersteuning voor meerdere domeinen â deel met een echt SSL-certificaat.
Met anti-spambeveiliging en een hoge anti-spamrating bij andere mailservers.
Met ondersteuning voor meerdere fysieke interfaces.
Met OpenVPN, waarmee je via IPv4 verbinding kunt maken, en dat IPv6 biedt.
Als je al deze technologieĂ«n niet wilt bestuderen, maar een dergelijke server wilt opzetten â dan is dit artikel voor jou.
In het artikel worden geen pogingen ondernomen om elk detail uit te leggen. De uitleg richt zich op wat niet standaard is ingesteld of belangrijk is vanuit het perspectief van de gebruiker.
De motivatie om een mailserver op te zetten â mijn oude droom. Misschien klinkt het stom, maar IMHO, dit is veel beter dan dromen over een nieuwe auto van mijn favoriete merk.
De motivatie om IPv6 in te stellen â twee. Een IT-specialist moet voortdurend nieuwe technologieĂ«n leren om te overleven. Ik wil een bescheiden bijdrage leveren aan de strijd tegen censuur.
De motivatie voor het instellen van OpenVPN â alleen zodat IPv6 op de lokale machine werkt.
De motivatie voor het instellen van meerdere fysieke interfaces â op mijn server heb ik één interface âtraag, maar onbeperktâ en een andere âsnel, maar met een tariefâ.
De motivatie om Bind in te stellen â mijn provider biedt een onbetrouwbare DNS-server, en Google heeft soms ook storingen. Ik wil een stabiele DNS-server voor persoonlijk gebruik.
De motivatie om een artikel te schrijven â de conceptversie werd 10 maanden geleden geschreven, en ik heb er al twee keer naar gekeken. Als zelfs de auteur dit regelmatig nodig heeft, is de kans groot dat anderen het ook nodig hebben.
Er is geen universele oplossing voor mailservers. Maar ik zal proberen te schrijven: 'doe dit en dan, als alles zoals het hoort werkt â gooi het overtollige weg'.
Er is een colocation-server bij het bedrijf tech.ru. Er is een mogelijkheid om te vergelijken met OVH, Hetzner, AWS. Voor deze taak is samenwerking met tech.ru veel efficiënter.
Op de server is Debian 9 geĂŻnstalleerd.
De server heeft 2 interfaces `eno1` en `eno2`. De eerste is onbeperkt, en de tweede is snel.
Er zijn 3 statische IP-adressen, XX.XX.XX.X0 en XX.XX.XX.X1 en XX.XX.XX.X2 op de interface `eno1` en XX.XX.XX.X5 op de interface `eno2`.
Er is een XXXX:XXXX:XXXX:XXXX::/64 pool van IPv6-adressen, die zijn toegewezen aan de interface `eno1` en uit daarvan XXXX:XXXX:XXXX:XXXX:1:2::/96 op mijn verzoek toegewezen aan `eno2`.
Er zijn 3 domeinen `domain1.com`, `domain2.com`, `domain3.com`. Voor `domain1.com` en `domain3.com` is er een SSL-certificaat.
Er is een Google-account waar ik de e-mailbox `vasya.pupkin@domain1.com` aan wil koppelen (e-mail ontvangen en verzenden via de Gmail-interface).
Er moet een e-mailbox zijn `support@domain2.com`, waarvan ik een kopie van de e-mails in mijn Gmail wil zien. En ik moet af en toe iets kunnen versturen namens `support@domain2.com` via de webinterface.
Er moet een e-mailbox zijn `ivanov@domain3.com`, die door Ivanov op zijn iPhone zal worden gebruikt.
Verstuurde e-mails moeten voldoen aan alle moderne anti-spam vereisten.
Er moet een het hoogste niveau van versleuteling zijn dat in openbare netwerken is voorzien.
Er moet ondersteuning zijn voor IPv6, zowel voor het verzenden als ontvangen van e-mails.
Er moet SpamAssassin zijn, dat nooit e-mails verwijdert. Het moet of bouncen, of doorgeven, of naar de IMAP-map 'Spam' sturen.
Er moet auto-training voor SpamAssassin zijn: als ik een e-mail naar de map 'Spam' verplaats, moet hij daarop leren; als ik een e-mail uit de map 'Spam' verplaats, moet hij daarop leren. De resultaten van de training van SpamAssassin moeten invloed hebben op de kans dat een e-mail in de map 'Spam' komt.
PHP-scripts moeten in staat zijn om e-mail te verzenden namens elk domein op deze server.
Er moet een OpenVPN-service zijn, met de mogelijkheid om IPv6 te gebruiken op een client zonder IPv6.
Eerst moeten de interfaces en routing worden ingesteld, inclusief IPv6.
Dan moet OpenVPN worden ingesteld, dat verbinding maakt via IPv4 en de client een statisch, echt IPv6-adres biedt. Deze client krijgt toegang tot alle IPv6-diensten op de server en toegang tot alle IPv6-bronnen op internet.
Daarna moet Postfix worden ingesteld voor het verzenden van e-mails + SPF + DKIM + rDNS en andere soortgelijke zaken.
Daarna moet Dovecot worden ingesteld en moet Multidomain worden geconfigureerd.
Daarna moet SpamAssassin worden ingesteld en moet de training worden geconfigureerd.
Tot slot moet Bind worden geĂŻnstalleerd.
============= Multi-interfaces =============
Voor het instellen van de interfaces moet het volgende in `\/etc\/network\/interfaces` worden geplaatst.
# The loopback network interface
auto lo
iface lo inet loopback
# The primary network interface
allow-hotplug eno1
iface eno1 inet static
address XX.XX.XX.X0/24
gateway XX.XX.XX.1
dns-nameservers 127.0.0.1 213.248.1.6
post-up ip route add XX.XX.XX.0/24 dev eno1 src XX.XX.XX.X0 table eno1t
post-up ip route add default via XX.XX.XX.1 table eno1t
post-up ip rule add table eno1t from XX.XX.XX.X0
post-up ip rule add table eno1t to XX.XX.XX.X0
auto eno1:1
iface eno1:1 inet static
address XX.XX.XX.X1
netmask 255.255.255.0
post-up ip rule add table eno1t from XX.XX.XX.X1
post-up ip rule add table eno1t to XX.XX.XX.X1
post-up ip route add 10.8.0.0/24 dev tun0 src XX.XX.XX.X1 table eno1t
post-down ip route del 10.8.0.0/24 dev tun0 src XX.XX.XX.X1 table eno1t
auto eno1:2
iface eno1:2 inet static
address XX.XX.XX.X2
netmask 255.255.255.0
post-up ip rule add table eno1t from XX.XX.XX.X2
post-up ip rule add table eno1t to XX.XX.XX.X2
iface eno1 inet6 static
address XXXX:XXXX:XXXX:XXXX:1:1::/64
gateway XXXX:XXXX:XXXX:XXXX::1
up ip -6 addr add XXXX:XXXX:XXXX:XXXX:1:1:1:1/64 dev $IFACE
up ip -6 addr add XXXX:XXXX:XXXX:XXXX:1:1:1:2/64 dev $IFACE
down ip -6 addr del XXXX:XXXX:XXXX:XXXX:1:1:1:1/64 dev $IFACE
down ip -6 addr del XXXX:XXXX:XXXX:XXXX:1:1:1:2/64 dev $IFACE
# The secondary network interface
allow-hotplug eno2
iface eno2 inet static
address XX.XX.XX.X5
netmask 255.255.255.0
post-up ip route add XX.XX.XX.0/24 dev eno2 src XX.XX.XX.X5 table eno2t
post-up ip route add default via XX.XX.XX.1 table eno2t
post-up ip rule add table eno2t from XX.XX.XX.X5
post-up ip rule add table eno2t to XX.XX.XX.X5
post-up ip route add 10.8.0.0/24 dev tun0 src XX.XX.XX.X5 table eno2t
post-down ip route del 10.8.0.0/24 dev tun0 src XX.XX.XX.X5 table eno2t
iface eno2 inet6 static
address XXXX:XXXX:XXXX:XXXX:1:2::/96
up ip -6 addr add XXXX:XXXX:XXXX:XXXX:1:2:1:1/64 dev $IFACE
up ip -6 addr add XXXX:XXXX:XXXX:XXXX:1:2:1:2/64 dev $IFACE
down ip -6 addr del XXXX:XXXX:XXXX:XXXX:1:2:1:1/64 dev $IFACE
down ip -6 addr del XXXX:XXXX:XXXX:XXXX:1:2:1:2/64 dev $IFACE
# OpenVPN network
iface tun0 inet6 static
address XXXX:XXXX:XXXX:XXXX:1:3::/80Deze instellingen kunnen op elke server in tech.ru worden toegepast (met een kleine afstemming met de ondersteuning) en zullen onmiddellijk correct werken.
Als je ervaring hebt met het instellen van soortgelijke dingen voor Hetzner, OVH â daar is het anders. Moeilijker.
eno1 is de naam van netwerkkaart #1 (langzaam, maar onbeperkt).
eno2 is de naam van netwerkkaart #2 (snel, maar met een tarief).
tun0 â de naam van de virtuele netwerkkaart van OpenVPN.
XX.XX.XX.X0 â IPv4 #1 op eno1.
XX.XX.XX.X1 â IPv4 #2 op eno1.
XX.XX.XX.X2 â IPv4 #3 op eno1.
XX.XX.XX.X5 â IPv4 #1 op eno2.
XX.XX.XX.1 â IPv4 gateway.
XXXX:XXXX:XXXX:XXXX::/64 â IPv6 voor de hele server.
XXXX:XXXX:XXXX:XXXX:1:2::/96 â IPv6 voor eno2, alles wat van buiten komt gaat via eno1.
XXXX:XXXX:XXXX:XXXX::1 â IPv6 gateway (het is vermeldenswaard dat dit anders kan/moet. De IPv6 van de switch moet hier worden opgegeven).
dns-nameservers â ingesteld op 127.0.0.1 (omdat bind lokaal is geĂŻnstalleerd) en 213.248.1.6 (dit is van tech.ru).
«table eno1t» en «table eno2t» â het idee van deze route-regel is dat verkeer dat binnenkomt via eno1 -> ook via eno1 vertrekt, en verkeer dat binnenkomt via eno2 -> ook via eno2 vertrekt. Daarnaast zou server-initiated verbindingen via eno1 moeten verlaten.
ip route add default via XX.XX.XX.1 table eno1tMet deze opdracht geven we aan dat elk onduidelijk verkeer dat valt onder een regel waarbij «table eno1t» is gemarkeerd -> naar de interface eno1 moet worden geleid.
ip route add XX.XX.XX.0/24 dev eno1 src XX.XX.XX.X0 table eno1tMet deze opdracht geven we aan dat elk verkeer dat door de server wordt geĂŻnitieerd naar de interface eno1 moet worden geleid.
ip rule add table eno1t from XX.XX.XX.X0
ip rule add table eno1t to XX.XX.XX.X0Met deze opdracht geven we de regels voor het markeren van verkeer op.
auto eno1:2
iface eno1:2 inet static
address XX.XX.XX.X2
netmask 255.255.255.0
post-up ip rule add table eno1t from XX.XX.XX.X2
post-up ip rule add table eno1t to XX.XX.XX.X2Dit blok stelt een tweede IPv4 in voor de interface eno1.
ip route add 10.8.0.0/24 dev tun0 src XX.XX.XX.X1 table eno1t Met deze opdracht geven we de route aan van OpenVPN-clients naar lokale IPv4, behalve XX.XX.XX.X0.
Waarom deze opdracht voldoende is voor alle IPv4 â ik begrijp het nog steeds niet.
iface eno1 inet6 static
address XXXX:XXXX:XXXX:XXXX:1:1::/64
gateway XXXX:XXXX:XXXX:XXXX::1Hier stellen we het adres voor de interface in. De server zal het gebruiken als het «uitgaande» adres. Het zal verder niet anders worden gebruikt.
Waarom is «:1:1::» zo complex aangegeven? Zodat OpenVPN goed werkt en alleen daarvoor. Meer hierover later.
Wat betreft de gateway â zo werkt het en dat is prima. Maar technisch gezien â hier moet de IPv6 van de switch worden opgegeven waaraan de server is verbonden.
Desondanks lijkt IPv6 niet te werken als ik het zo doe. Het zijn waarschijnlijk wat eigenaardigheden van tech.ru.
ip -6 addr add XXXX:XXXX:XXXX:XXXX:1:1:1:1/64 dev $IFACEDit voegt een IPv6-adres toe aan de interface. Als er honderd adressen nodig zijn â dan zijn er honderd regels in dit bestand.
iface eno1 inet6 static
address XXXX:XXXX:XXXX:XXXX:1:1::/64
...
iface eno2 inet6 static
address XXXX:XXXX:XXXX:XXXX:1:2::/96
...
iface tun0 inet6 static
address XXXX:XXXX:XXXX:XXXX:1:3::/80Ik heb de adressen en subnetten van alle interfaces gemarkeerd voor een duidelijk overzicht.
eno1 â moet absoluut «/64» zijn â omdat dit ons volledige pool van adressen is.
tun0 â het subnet moet absoluut groter zijn dan eno1. Anders kan de IPv6-gateway voor OpenVPN-klanten niet worden ingesteld.
eno2 â het subnet moet absoluut groter zijn dan tun0. Anders kunnen OpenVPN-klanten de lokale IPv6-adressen niet bereiken.
Voor de duidelijkheid heb ik een subnetstap van 16 gekozen, maar desgewenst kan de stap zelfs «1» zijn.
Dus 64+16 = 80, en 80+16 = 96.Voor nog meer duidelijkheid:
XXXX:XXXX:XXXX:XXXX:1:1:YYYY:YYYY â dit zijn de adressen die aan specifieke websites of diensten op de interface eno1 moeten worden toegewezen.
XXXX:XXXX:XXXX:XXXX:1:2:YYYY:YYYY â dit zijn de adressen die aan specifieke websites of diensten op de interface eno2 moeten worden toegewezen.
XXXX:XXXX:XXXX:XXXX:1:3:YYYY:YYYY â dit zijn de adressen die aan OpenVPN-klanten moeten worden toegewezen of als service-adressen voor OpenVPN moeten worden gebruikt.
Voor het configureren van het netwerk â moet de mogelijkheid zijn om de server te herstarten.
IPv4-wijzigingen worden opgepikt bij het uitvoeren (vergeet niet om in screen te draaien â anders zal deze opdracht simpelweg het netwerk op de server uitschakelen):
/etc/init.d/networking restartVoeg het volgende toe aan het bestand «/etc/iproute2/rt_tables»:
100 eno1t
101 eno2t Zonder dit kunnen aangepaste tabellen in het bestand «/etc/network/interfaces» niet worden gebruikt.
De cijfers moeten uniek zijn en minder dan 65535.
IPv6-wijzigingen kunnen eenvoudig worden aangepast zonder herstarten, maar daarvoor moet je minimaal drie commando's leren:
ip -6 addr ...
ip -6 route ...
ip -6 neigh ...Configuratie van «/etc/sysctl.conf»
# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.ip_forward = 1
# Do not accept ICMP redirects (prevent MITM attacks)
net.ipv4.conf.all.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
# Do not send ICMP redirects (we are not a router)
net.ipv4.conf.all.send_redirects = 0
# For receiving ARP replies
net.ipv4.conf.all.arp_filter = 0
net.ipv4.conf.default.arp_filter = 0
# For sending ARP
net.ipv4.conf.all.arp_announce = 0
net.ipv4.conf.default.arp_announce = 0
# Enable IPv6
net.ipv6.conf.all.disable_ipv6 = 0
net.ipv6.conf.default.disable_ipv6 = 0
net.ipv6.conf.lo.disable_ipv6 = 0
# IPv6 configuration
net.ipv6.conf.all.autoconf = 1
net.ipv6.conf.all.accept_ra = 0
# For OpenVPN
net.ipv6.conf.all.forwarding = 1
net.ipv6.conf.all.proxy_ndp = 1
# For nginx on boot
net.ipv6.ip_nonlocal_bind = 1Dit zijn de «sysctl»-instellingen van mijn server. Ik wil iets belangrijks benadrukken.
net.ipv4.ip_forward = 1Zonder dit zal OpenVPN helemaal niet werken.
net.ipv6.ip_nonlocal_bind = 1Iedereen die probeert IPv6 te binden (bijvoorbeeld nginx) meteen nadat de interface is opgestart, krijgt een foutmelding dat zo'n adres niet beschikbaar is.
Om zo'n situatie te voorkomen, wordt deze instelling gedaan.
net.ipv6.conf.all.forwarding = 1
net.ipv6.conf.all.proxy_ndp = 1Zonder deze instellingen komt IPv6-verkeer van de OpenVPN-klant de wereld niet in.
Andere instellingen zijn of niet relevant of ik weet niet meer waarom ze er zijn.
Maar voor alle zekerheid laat ik ze âzoals ze zijnâ.
Om ervoor te zorgen dat wijzigingen in dit bestand zonder herstarten van de server worden opgepikt â moet het commando worden uitgevoerd:
sysctl -pMeer details over «table» regels:
============= OpenVPN =============
OpenVPN IPv4 werkt niet zonder iptables.
Mijn iptables zijn als volgt ingesteld voor VPN:
iptables -A INPUT -p udp -s YY.YY.YY.YY --dport 1194 -j ACCEPT
iptables -A FORWARD -i tun0 -o eno1 -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eno1 -j SNAT --to-source XX.XX.XX.X0
##iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eno1 -j MASQUERADE
iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -p udp --dport 1194 -j DROP
iptables -A FORWARD -p udp --dport 1194 -j DROP YY.YY.YY.YY â dit is mijn statische IPv4-adres van de lokale machine.
10.8.0.0/24 â IPv4-netwerk van openvpn. IPv4-adressen voor openvpn-clients.
De volgorde van de regels is belangrijk.
iptables -A INPUT -p udp -s YY.YY.YY.YY --dport 1194 -j ACCEPT
iptables -A FORWARD -i tun0 -o eno1 -j ACCEPT
...
iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -p udp --dport 1194 -j DROP
iptables -A FORWARD -p udp --dport 1194 -j DROPDit is een beperking zodat alleen ik vanaf mijn statische IP gebruik kan maken van OpenVPN.
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eno1 -j SNAT --to-source XX.XX.XX.X0
-- of --
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eno1 -j MASQUERADEOm IPv4-pakketten tussen OpenVPN-clients en het internet door te geven â moet je een van deze opdrachten invoeren.
Voor verschillende gevallen past een van de opties niet.
Voor mijn geval passen beide commando's.
Na het lezen van de documentatie koos ik de eerste optie, omdat deze minder CPU verbruikt.
Om ervoor te zorgen dat alle iptables-instellingen na een reboot worden opgepakt â moet je ze ergens opslaan.
iptables-save > /etc/iptables/rules.v4
ip6tables-save > /etc/iptables/rules.v6Deze namen zijn niet toevallig gekozen. Ze worden gebruikt door het pakket "iptables-persistent".
apt-get install iptables-persistentInstallatie van het hoofd pakket OpenVPN:
apt-get install openvpn easy-rsaLaten we een sjabloon instellen voor de certificaten (vervang door je eigen waarden):
make-cadir ~/openvpn-ca
cd ~/openvpn-ca
ln -s openssl-1.0.0.cnf openssl.cnfLaten we de instellingen van het certificaatsjabloon bewerken:
mcedit vars# Dit zijn de standaardwaarden voor velden
# die in het certificaat worden geplaatst.
# Laat geen van deze velden leeg.
export KEY_COUNTRY="RU"
export KEY_PROVINCE="Krasnodar"
export KEY_CITY="Dinskaya"
export KEY_ORG="Eigen"
export KEY_EMAIL="admin@domain1.com"
export KEY_OU="VPN"
# X509 Onderwerp Veld
export KEY_NAME="server"
...We maken een servercertificaat:
cd ~/openvpn-ca
source vars
./clean-all
./build-ca
./build-key-server server
./build-dh
openvpn --genkey --secret keys/ta.keyLaten we de mogelijkheid voorbereiden om eindbestanden "client-name.opvn" te creëren:
mkdir -p ~/client-configs/files
chmod 700 ~/client-configs/files
cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf ~/client-configs/base.conf
mcedit ~/client-configs/base.conf# Client mode
client
# Interface tunnel type
dev tun
# TCP protocol
proto tcp-client
# Address/Port of VPN server
remote XX.XX.XX.X0 1194
# Don't bind to local port/address
nobind
# Don't need to re-read keys and re-create tun at restart
persist-key
persist-tun
# Remote peer must have a signed certificate
remote-cert-tls server
ns-cert-type server
# Enable compression
comp-lzo
# Custom
ns-cert-type server
tls-auth ta.key 1
cipher DES-EDE3-CBCLaten we een script voorbereiden dat alle bestanden in één opvn-bestand samenvoegt.
mcedit ~/client-configs/make_config.sh
chmod 700 ~/client-configs/make_config.sh#!/bin/bash
# First argument: Client identifier
KEY_DIR=~/openvpn-ca/keys
OUTPUT_DIR=~/client-configs/files
BASE_CONFIG=~/client-configs/base.conf
cat ${BASE_CONFIG}
<(echo -e '<ca>')
${KEY_DIR}/ca.crt
<(echo -e '</ca>n<cert>')
${KEY_DIR}/${1}.crt
<(echo -e '</cert>n<key>')
${KEY_DIR}/${1}.key
<(echo -e '</key>n<tls-auth>')
${KEY_DIR}/ta.key
<(echo -e '</tls-auth>')
> ${OUTPUT_DIR}/${1}.ovpnWe maken de eerste OpenVPN-client:
cd ~/openvpn-ca
source vars
./build-key client-name
cd ~/client-configs
./make_config.sh client-nameHet bestand "~/client-configs/files/client-name.ovpn" sturen we naar het apparaat van de klant.
Voor iOS-klanten moet een truc worden uitgevoerd:
De inhoud van de tag «tls-auth» moet zonder opmerkingen zijn.
En zet «key-direction 1» direct voor de tag «tls-auth».
Laten we de configuratie van de OpenVPN-server instellen:
cd ~/openvpn-ca/keys
cp ca.crt ca.key server.crt server.key ta.key dh2048.pem /etc/openvpn
gunzip -c /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz | tee /etc/openvpn/server.conf
mcedit /etc/openvpn/server.conf# Listen port
port 1194
# Protocol
proto tcp-server
# IP tunnel
dev tun0
tun-ipv6
push tun-ipv6
# Master certificate
ca ca.crt
# Server certificate
cert server.crt
# Server private key
key server.key
# Diffie-Hellman parameters
dh dh2048.pem
# Allow clients to communicate with each other
client-to-client
# Client config dir
client-config-dir /etc/openvpn/ccd
# Run client-specific script on connection and disconnection
script-security 2
client-connect "/usr/bin/sudo -u root /etc/openvpn/server-clientconnect.sh"
client-disconnect "/usr/bin/sudo -u root /etc/openvpn/server-clientdisconnect.sh"
# Server mode and client subnets
server 10.8.0.0 255.255.255.0
server-ipv6 XXXX:XXXX:XXXX:XXXX:1:3::/80
topology subnet
# IPv6 routes
push "route-ipv6 XXXX:XXXX:XXXX:XXXX::/64"
push "route-ipv6 2000::/3"
# DNS (for Windows)
# These are OpenDNS
push "dhcp-option DNS 208.67.222.222"
push "dhcp-option DNS 208.67.220.220"
# Configure all clients to redirect their default network gateway through the VPN
push "redirect-gateway def1 bypass-dhcp"
push "redirect-gateway ipv6" #For iOS
# Don't need to re-read keys and re-create tun at restart
persist-key
persist-tun
# Ping every 10s. Timeout of 120s.
keepalive 10 120
# Enable compression
comp-lzo
# User and group
user vpn
group vpn
# Log a short status
status openvpn-status.log
# Logging verbosity
##verb 4
# Custom config
tls-auth ta.key 0
cipher DES-EDE3-CBCDit is nodig om een statisch adres aan elke klant toe te wijzen (niet verplicht, maar ik gebruik het):
# Client config dir
client-config-dir /etc/openvpn/ccdHet meest complexe en cruciale detail.
Helaas kan OpenVPN nog niet automatisch een IPv6-gateway voor klanten configureren.
Dit moet «handmatig» voor elke klant worden doorgestuurd.
# Run client-specific script on connection and disconnection
script-security 2
client-connect "/usr/bin/sudo -u root /etc/openvpn/server-clientconnect.sh"
client-disconnect "/usr/bin/sudo -u root /etc/openvpn/server-clientdisconnect.sh"Bestand «/etc/openvpn/server-clientconnect.sh»:
#!/bin/sh
# Check client variables
if [ -z "$ifconfig_pool_remote_ip" ] || [ -z "$common_name" ]; then
echo "Missing environment variable."
exit 1
fi
# Load server variables
. /etc/openvpn/variables
ipv6=""
# Find out if there is a specific config with fixed IPv6 for this client
if [ -f "/etc/openvpn/ccd/$common_name" ]; then
# Get fixed IPv6 from client config file
ipv6=$(sed -nr 's/^.*ifconfig-ipv6-push[ t]+([0-9a-fA-F:]+).*$/1/p' "/etc/openvpn/ccd/$common_name")
echo $ipv6
fi
# Get IPv6 from IPv4
if [ -z "$ipv6" ]; then
ipp=$(echo "$ifconfig_pool_remote_ip" | cut -d. -f4)
if ! [ "$ipp" -ge 2 -a "$ipp" -le 254 ] 2>/dev/null; then
echo "Invalid IPv4 part."
exit 1
fi
hexipp=$(printf '%x' $ipp)
ipv6="$prefix$hexipp"
fi
# Create proxy rule
/sbin/ip -6 neigh add proxy $ipv6 dev eno1Bestand «/etc/openvpn/server-clientdisconnect.sh»:
#!/bin/sh
# Check client variables
if [ -z "$ifconfig_pool_remote_ip" ] || [ -z "$common_name" ]; then
echo "Missing environment variable."
exit 1
fi
# Load server variables
. /etc/openvpn/variables
ipv6=""
# Find out if there is a specific config with fixed IPv6 for this client
if [ -f "/etc/openvpn/ccd/$common_name" ]; then
# Get fixed IPv6 from client config file
ipv6=$(sed -nr 's/^.*ifconfig-ipv6-push[ t]+([0-9a-fA-F:]+).*$/1/p' "/etc/openvpn/ccd/$common_name")
fi
# Get IPv6 from IPv4
if [ -z "$ipv6" ]; then
ipp=$(echo "$ifconfig_pool_remote_ip" | cut -d. -f4)
if ! [ "$ipp" -ge 2 -a "$ipp" -le 254 ] 2>/dev/null; then
echo "Invalid IPv4 part."
exit 1
fi
hexipp=$(printf '%x' $ipp)
ipv6="$prefix$hexipp"
fi
# Delete proxy rule
/sbin/ip -6 neigh del proxy $ipv6 dev eno1Beide scripts gebruiken het bestand «/etc/openvpn/variables»:
# Subnet
prefix=XXXX:XXXX:XXXX:XXXX:2:
# netmask
prefixlen=112Waarom dit zo is geschreven, kan ik me niet herinneren.
Het ziet er nu vreemd uit, netmask = 112 (hier moet 96 zijn).
En de prefix is vreemd, komt niet overeen met het tun0-netwerk.
Maar goed, ik laat het «zoals het is».
cipher DES-EDE3-CBCDit is voor de liefhebbers â ik heb voor deze versleuteling van de verbinding gekozen.
============= Postfix =============
Installatie van het hoofdpakket:
apt-get install postfixKies tijdens de installatie «internet-site».
Mijn «/etc/postfix/main.cf» ziet er als volgt uit:
smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU)
biff = nee
# Het toevoegen van .domain is de taak van de MUA.
append_dot_mydomain = nee
readme_directory = nee
# Zie http://www.postfix.org/COMPATIBILITY_README.html -- standaard op 2 voor
# nieuwe installaties.
compatibility_level = 2
# TLS-parameters
smtpd_tls_cert_file=/etc/ssl/domain1.com.2018.chained.crt
smtpd_tls_key_file=/etc/ssl/domain1.com.2018.key
smtpd_use_tls=ja
smtpd_tls_auth_only = ja
smtp_bind_address = XX.XX.XX.X0
smtp_bind_address6 = XXXX:XXXX:XXXX:XXXX:1:1:1:1
smtp_tls_security_level = mag
smtp_tls_ciphers = export
smtp_tls_protocols = !SSLv2, !SSLv3
smtp_tls_loglevel = 1
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
myhostname = domain1.com
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = domain1.com
mydestination = localhost
relayhost =
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
inet_protocols = ipv4
internal_mail_filter_classes = bounce
# Opslagtype
virtual_transport = lmtp:unix:private/dovecot-lmtp
virtual_mailbox_domains = mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf
virtual_mailbox_maps = mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
virtual_alias_maps = mysql:/etc/postfix/mysql-virtual-alias-maps.cf
# SMTP-Auth instellingen
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = ja
smtpd_recipient_restrictions =
permit_sasl_authenticated,
permit_mynetworks,
#reject_invalid_hostname,
#reject_unknown_recipient_domain,
reject_unauth_destination,
reject_rbl_client sbl.spamhaus.org,
check_policy_service unix:private/policyd-spf
smtpd_helo_restrictions =
#reject_invalid_helo_hostname,
#reject_non_fqdn_helo_hostname,
reject_unknown_helo_hostname
smtpd_client_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
reject_non_fqdn_helo_hostname,
permit
# SPF
policyd-spf_time_limit = 3600
# OpenDKIM
milter_default_action = accept
milter_protocol = 6
smtpd_milters = unix:var/run/opendkim/opendkim.sock
non_smtpd_milters = unix:var/run/opendkim/opendkim.sock
# IP-adres per domein
sender_dependent_default_transport_maps = pcre:/etc/postfix/sdd_transport.pcreLaten we de details van deze configuratie bekijken.
smtpd_tls_cert_file=/etc/ssl/domain1.com.2018.chained.crt
smtpd_tls_key_file=/etc/ssl/domain1.com.2018.keyDe mening van de Habr-lezer is dat dit blok 'desinformatie en onjuiste stellingen' bevat.Pas 8 jaar na het begin van mijn carriĂšre begon ik te begrijpen hoe SSL werkt.
Daarom neem ik de vrijheid om te beschrijven hoe je SSL kunt gebruiken (zonder te antwoorden op vragen als 'Hoe werkt dit?' en 'Waarom werkt dit?').
De basis van moderne encryptie is het creëren van een paar sleutels (twee zeer lange tekenreeksen).
De ene 'sleutel' is privé, de andere sleutel is 'publiek'. We houden de privésleutel met grote zorg geheim. De publieke sleutel geven we aan iedereen.
Met de publieke sleutel kan een tekstregel worden versleuteld, zodat alleen de eigenaar van de privésleutel deze kan ontsleutelen.
Dat is de basis van de technologie.Stap nr. 1 â https-websites.
Wanneer een browser toegang zoekt tot een website, krijgt hij van de webserver te horen dat de site https is en vraagt daarom om de publieke sleutel.
De webserver geeft de publieke sleutel vrij. De browser gebruikt de publieke sleutel om de http-aanroep te versleutelen en verstuurt deze.
De inhoud van de http-aanroep kan alleen worden gelezen door degene die de private sleutel heeft, dus alleen de server waarnaar de aanvraag wordt gedaan.
Een http-aanroep bevat minimaal een URI. Dus, als in een land getracht wordt de toegang niet tot de gehele website te beperken, maar tot een specifieke pagina â dan is dit voor https-sites onmogelijk.Stap â2 â versleuteld antwoord.
De webserver geeft een antwoord dat gemakkelijk onderweg kan worden gelezen.
De oplossing is uiterst eenvoudig â de browser genereert lokaal een vergelijkbaar paar van private en publieke sleutels voor elke https-site.
En samen met de aanvraag voor de publieke sleutel van de site, verzendt deze zijn lokale publieke sleutel.
De webserver onthoudt deze en versleutelt de http-response met deze publieke sleutel van de specifieke klant.
Nu kan de http-response alleen worden ontsleuteld door de houder van de private sleutel van de browser van de klant (namelijk de klant zelf).Stap â3 â het opzetten van een veilige verbinding via een publiek kanaal.
In voorbeeld â2 bestaat er een kwetsbaarheid â er is niets dat een kwaadwillende zou kunnen tegenhouden om de http-aanroep te onderscheppen en de informatie over de publieke sleutel te bewerken.
Hierdoor kan de tussenpersoon de hele inhoud van de verzonden en ontvangen berichten perfect zien totdat het communic kanaal wordt veranderd.
Om dit te bestrijden is het uiterst eenvoudig â het is voldoende om de publieke sleutel van de browser te verzenden als een bericht dat is versleuteld met de publieke sleutel van de webserver.
De webserver stuurt dan als eerste antwoord iets als âjouw publieke sleutel is zo en zoâ en versleutelt dit bericht met dezelfde publieke sleutel.
De browser bekijkt het antwoord â als het bericht 'jouw publieke sleutel is zo en zo' is gekomen â dan is dit 100% garantie dat deze communicatie veilig is.
Hoe veilig is het?
De creatie van zo'n veilige communicatiekanaal gebeurt met een snelheid van ping*2. Bijvoorbeeld 20ms.
Een aanvaller moet ofwel van tevoren de private sleutel van een van de partijen hebben. Of de private sleutel in een paar milliseconden kunnen raden.
Het kraken van één moderne private sleutel zou tientallen jaren duren op een supercomputer.Stap â4 â publieke database van publieke sleutels.
Het is duidelijk dat er in dit verhaal een mogelijkheid bestaat voor een kwaadwillende die zich op het communicatiekanaal tussen klant en server bevindt.
De mogelijkheid voor de klant om zich voor te stellen als server, en de server om zich voor te stellen als klant. En om een paar sleutels in beide richtingen te simuleren.
Dan zal de aanvaller al het verkeer kunnen zien en heeft hij de mogelijkheid om het verkeer 'te bewerken'.
Bijvoorbeeld om het adres te veranderen waar geld naartoe gestuurd moet worden of om het wachtwoord van de online bank te kopiëren of om 'ongewenste' inhoud te blokkeren.
Om tegen dergelijke aanvallers te vechten, is er een openbare database met openbare sleutels voor elke https-website bedacht.
Elke browser 'weet' dat er ongeveer 200 van dergelijke databases bestaan. Dit is vooraf ingesteld in elke browser.
'Kennis' wordt ondersteund door een openbare sleutel van elk certificaat. Dat betekent dat het onmogelijk is om de verbinding met elk specifiek certificeringscentrum te vervalsen.Nu is er een eenvoudig begrip van hoe SSL voor https te gebruiken.
Als je je hersens gebruikt, wordt duidelijk hoe inlichtingendiensten in deze constructie iets kunnen hacken. Maar dat kost hen een enorme inspanning.
Voor organisaties ligt het niveau van bescherming dat het NSA of de CIA biedt â praktisch onmogelijk om te breken, zelfs voor VIP's.Ik voeg nog iets toe over ssh-verbindingen. Daar zijn geen openbare sleutels, wat nu te doen? De vraag wordt op twee manieren opgelost.
Optie ssh-per-wachtwoord:
Bij de eerste verbinding moet de ssh-client waarschuwen dat hier een nieuwe openbare sleutel van de ssh-server is.
En bij verdere verbindingen, als er een waarschuwing verschijnt 'nieuwe openbare sleutel van de ssh-server' â betekent dat dat men probeert af te luisteren.
Of bij de eerste verbinding is u afgeluisterd, en nu communiceert u met de server zonder tussenpersonen.
Eigenlijk wordt deze aanval alleen in bijzondere gevallen op een specifieke klant gebruikt omdat het feit van afluisteren gemakkelijk, snel en zonder inspanning kan worden ontdekt.Optie ssh-per-sleutel:
Neem een USB-stick, schrijf de privé-sleutel voor de ssh-server erop (hiervoor zijn termen en veel belangrijke nuances, maar ik schrijf educatieve informatie, geen handleiding).
De openbare sleutel blijft op de machine waar de ssh-client zich bevindt en houden we ook geheim.
We brengen de USB-stick naar de server, steken deze in, kopiëren de privé-sleutel, en verbranden de USB-stick en verspreiden de as over de wind (of formatteren deze op zijn minst met nullen).
Dat is alles â na zo'n operatie zal het onmogelijk zijn om zo'n ssh-verbinding te kraken. Over het algemeen kan men na zo'n 10 jaar op een supercomputer misschien het verkeer bekijken â maar dat is een ander verhaal.Mijn excuses voor de off-topic.
Dus nu we de theorie kennen, zal ik het proces van het creëren van een ssl-certificaat uitleggen.
Met behulp van «openssl genrsa» creëren we een privésleutel en «voorbereidingen» voor de publieke sleutel.
De «voorbereidingen» sturen we naar een extern bedrijf waarvoor we ongeveer $9 betalen voor het eenvoudigste certificaat.
Na een paar uur ontvangen we van dit externe bedrijf onze «publieke» sleutel en bovendien een set van verschillende publieke sleutels.
Waarom betalen we een extern bedrijf voor het maken van mijn publieke sleutel â dat is een aparte kwestie, die zullen we hier niet behandelen.
Het is nu duidelijk wat de betekenis van de tekst is:
smtpd_tls_key_file= /etc/ssl/domain1.com.2018.key In de map «/etc/ssl» zijn alle bestanden voor ssl-zaken opgeslagen.
domain1.com â de naam van het domein.
2018 â het jaar waarin de sleutels zijn gemaakt.
«key» â geeft aan dat het bestand een privĂ©sleutel is.
En de betekenis van dit bestand is:
smtpd_tls_cert_file= /etc/ssl/domain1.com.2018.chained.crt
domain1.com â de naam van het domein.
2018 â het jaar waarin de sleutels zijn gemaakt.
chained â geeft aan dat hier een keten van publieke sleutels is (de eerste â onze publieke sleutel en de overige â die afkomstig zijn van het bedrijf dat de publieke sleutel heeft afgehandeld).
crt â geeft aan dat hier een voltooid certificaat is (publieke sleutel met technische toelichtingen).
smtp_bind_address = XX.XX.XX.X0
smtp_bind_address6 = XXXX:XXXX:XXXX:XXXX:1:1:1:1Deze instelling wordt in dit geval niet gebruikt, maar is geschreven als voorbeeld.
Want een fout in deze parameter kan leiden tot het verzenden van spam vanaf uw server (zonder uw toestemming).
Daarna moet u iedereen overtuigen dat u niet schuldig bent.
recipient_delimiter = +Misschien weet niet iedereen dit, maar dit is het standaard symbool voor het rangschikken van e-mails, en dit wordt door de meeste moderne mailservers ondersteund.
Bijvoorbeeld, als u een e-mailadres «username@gmail.com» heeft, probeer dan te verzenden naar «username+spam@gmail.com» â kijk wat daaruit komt.
inet_protocols = ipv4Misschien zal dit je in de war brengen.
Maar dat is niet zomaar. Elke nieuwe domein is standaard alleen IPv4, daarna schakel ik IPv6 in voor elk domein afzonderlijk.
virtual_transport = lmtp:unix:private/dovecot-lmtp
virtual_mailbox_domains = mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf
virtual_mailbox_maps = mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
virtual_alias_maps = mysql:/etc/postfix/mysql-virtual-alias-maps.cf Hier geven we aan dat alle inkomende e-mails naar dovecot gaan.
En de regels voor domeinen, mailboxen, aliassen â deze bekijken in de database.
/etc/postfix/mysql-virtual-mailbox-domains.cf
user = usermail
password = mailpassword
hosts = 127.0.0.1
dbname = servermail
query = SELECT 1 FROM virtual_domains WHERE name='%s'/etc/postfix/mysql-virtual-mailbox-maps.cf
user = usermail
password = mailpassword
hosts = 127.0.0.1
dbname = servermail
query = SELECT 1 FROM virtual_users WHERE email='%s'/etc/postfix/mysql-virtual-alias-maps.cf
user = usermail
password = mailpassword
hosts = 127.0.0.1
dbname = servermail
query = SELECT destination FROM virtual_aliases WHERE source='%s'# SMTP-Auth settings
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yesNu weet postfix dat het alleen e-mail voor verdere verzending kan accepteren met autorisatie van dovecot.
Ik begrijp echt niet goed waarom dit hier gedupliceerd moet worden. We hebben al alles wat nodig is aangegeven in 'virtual_transport'.
Maar de postfix-systeem is erg oud â misschien zijn dit noodoplossingen uit vroegere tijden.
smtpd_recipient_restrictions =
...
smtpd_helo_restrictions =
...
smtpd_client_restrictions =
...Dit moet voor elke mailserver afzonderlijk worden ingesteld.
Ik heb drie mailservers tot mijn beschikking en deze instellingen verschillen sterk vanwege verschillende gebruikseisen.
Je moet voorzichtig configureren â anders zal spam naar je toestromen of nog erger â spam zal van jou afkomstig zijn.
# SPF
policyd-spf_time_limit = 3600Configuratie voor een of andere plugin gerelateerd aan de controle van SPF van binnenkomende e-mails.
# OpenDKIM
milter_default_action = accept
milter_protocol = 6
smtpd_milters = unix:var/run/opendkim/opendkim.sock
non_smtpd_milters = unix:var/run/opendkim/opendkim.sockInstelling dat we alle uitgaande e-mails moeten voorzien van een DKIM-handtekening.
# IP address per domain
sender_dependent_default_transport_maps = pcre:/etc/postfix/sdd_transport.pcreDit is een cruciaal detail in de routering van e-mails bij het verzenden van e-mails vanaf php-scripts.
Bestand "\/etc\/postfix\/sdd_transport.pcre":
/^www-domain1@domain1.com$/ domain1:
/^www-domain2@domain1.com$/ domain2:
/^www-domain3@domain1.com$/ domain3:
/@domain1.com$/ domain1:
/@domain2.com$/ domain2:
/@domain3.com$/ domain3:Links staan de reguliere uitdrukkingen. Rechts staat het label dat aan de e-mail wordt toegekend.
Postfix houdt rekening met nog enkele configuratieregels voor de specifieke e-mail op basis van het label.Hoe precies postfix opnieuw geconfigureerd zal worden voor de specifieke e-mail wordt aangegeven in 'master.cf'.
Regels 4, 5, 6 â dat zijn de belangrijkste. Onder welke domeinnaam we de e-mail verzenden, dat label gebruiken we.
Maar niet altijd geven php-scripts in de oude code het 'from'-veld op. Dan komt de gebruikersnaam van pas.Het artikel is al uitgebreid â ik wil me niet afleiden met de configuratie van nginx+fpm.
Kortom â we stellen voor elke website een eigen linux-gebruiker in. En daarmee dus zijn eigen fpm-pool.
Fpm-pool gebruikt elke versie van php (het is geweldig wanneer je op één server zonder problemen verschillende versies van php en zelfs verschillende php.ini voor aangrenzende websites kunt gebruiken).
Dus voor de specifieke linux-gebruiker 'www-domain2' is er een website domain2.com. Op deze website is er code voor het verzenden van e-mails zonder het 'from'-veld op te geven.
Zelfs in dat geval zullen e-mails correct vertrekken en nooit in de spam terechtkomen.
Mijn '\/etc\/postfix\/master.cf' ziet er als volgt uit:
...
smtp inet n - y - - smtpd
-o content_filter=spamassassin
...
submission inet n - y - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
...
policyd-spf unix - n n - 0 spawn
user=policyd-spf argv=/usr/bin/policyd-spf
spamassassin unix - n n - - pipe
user=spamd argv=/usr/bin/spamc -f -e
/usr/sbin/sendmail -oi -f ${sender} ${recipient}
...
domain1 unix - - n - - smtp
-o smtp_bind_address=XX.XX.XX.X1
-o smtp_helo_name=domain1.com
-o inet_protocols=all
-o smtp_bind_address6=XXXX:XXXX:XXXX:XXXX:1:1:1:1
-o syslog_name=postfix-domain1
domain2 unix - - n - - smtp
-o smtp_bind_address=XX.XX.XX.X5
-o smtp_helo_name=domain2.com
-o inet_protocols=all
-o smtp_bind_address6=XXXX:XXXX:XXXX:XXXX:1:2:1:1
-o syslog_name=postfix-domain2
domain3 unix - - n - - smtp
-o smtp_bind_address=XX.XX.XX.X2
-o smtp_helo_name=domain3
-o inet_protocols=all
-o smtp_bind_address6=XXXX:XXXX:XXXX:XXXX:1:1:5:1
-o syslog_name=postfix-domain3 Het bestand is niet volledig weergegeven â het is al erg groot.
Ik heb alleen gemarkeerd wat is veranderd.
smtp inet n - y - - smtpd
-o content_filter=spamassassin
...
spamassassin unix - n n - - pipe
user=spamd argv=/usr/bin/spamc -f -e
/usr/sbin/sendmail -oi -f ${sender} ${recipient}Dit zijn de instellingen met betrekking tot spamassassin, daarover later meer.
submission inet n - y - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_client_restrictions=permit_sasl_authenticated,reject We staan verbinding toe met de mailserver via poort 587.
Voor deze stap is autorisatie vereist.
policyd-spf unix - n n - 0 spawn
user=policyd-spf argv=/usr/bin/policyd-spfWe schakelen SPF-controle in.
apt-get install postfix-policyd-spf-pythonWe installeren het pakket voor de SPF-controles hierboven.
domain1 unix - - n - - smtp
-o smtp_bind_address=XX.XX.XX.X1
-o smtp_helo_name=domain1.com
-o inet_protocols=all
-o smtp_bind_address6=XXXX:XXXX:XXXX:XXXX:1:1:1:1
-o syslog_name=postfix-domain1En dit is het interessantste. Dit is de mogelijkheid om e-mails te verzenden voor een specifiek domein vanaf een specifiek IPv4/IPv6 adres.
Dit wordt gedaan voor rDNS. rDNS is het verkrijgen van een bepaalde string op basis van een IP-adres.
En voor e-mail wordt deze mogelijkheid gebruikt om te bevestigen dat het helo daadwerkelijk overeenkomt met de rDNS van het adres waarvan de e-mail is verzonden.Als het helo niet overeenkomt met het maildomein waarvan de e-mail is verzonden, worden er spampunten toegekend.
Helo komt niet overeen met de rDNS â er worden veel spampunten toegekend.
Daarom moet elk domein zijn eigen IP-adres hebben.
Voor OVH is er de mogelijkheid om rDNS in het controlepaneel in te stellen.
Voor tech.ru kan dit probleem via de support worden opgelost.
Voor AWS kan dit probleem ook via de support worden opgelost.
«inet_protocols» en «smtp_bind_address6» â hiermee schakelen we de ondersteuning voor IPv6 in.
Voor IPv6 moet rDNS ook worden ingesteld.
«syslog_name» â dit is voor het gemak van het lezen van logs.
Certificaten kopen .
.
============= Dovecot =============
apt-get install dovecot-imapd dovecot-pop3d dovecot-lmtpd dovecot-mysql dovecot-antispamMySQL-configuratie, we installeren zelf de pakketten.
Bestand «/etc/dovecot/conf.d/10-auth.conf»
disable_plaintext_auth = yes
auth_mechanisms = plain loginAutorisatie alleen in versleutelde vorm.
Bestand «/etc/dovecot/conf.d/10-mail.conf»
mail_location = maildir:/var/mail/vhosts/%d/%nHier geven we de opslaglocatie van e-mails op.
Ik wil dat ze in bestanden worden opgeslagen en gegroepeerd per domein.
Bestand «/etc/dovecot/conf.d/10-master.conf»
service imap-login {
inet_listener imap {
port = 0
}
inet_listener imaps {
address = XX.XX.XX.X1, XX.XX.XX.X2, XX.XX.XX.X5, [XXXX:XXXX:XXXX:XXXX:1:1:1:1], [XXXX:XXXX:XXXX:XXXX:1:2:1:1], [XXXX:XXXX:XXXX:XXXX:1:1:5:1]
port = 993
ssl = yes
}
}
service pop3-login {
inet_listener pop3 {
port = 0
}
inet_listener pop3s {
address = XX.XX.XX.X1, XX.XX.XX.X2, XX.XX.XX.X5, [XXXX:XXXX:XXXX:XXXX:1:1:1:1], [XXXX:XXXX:XXXX:XXXX:1:2:1:1], [XXXX:XXXX:XXXX:XXXX:1:1:5:1]
port = 995
ssl = yes
}
}
service lmtp {
unix_listener /var/spool/postfix/private/dovecot-lmtp {
mode = 0600
user = postfix
group = postfix
}
}
service imap {
}
service pop3 {
}
service auth {
unix_listener auth-userdb {
mode = 0600
user = vmail
}
unix_listener /var/spool/postfix/private/auth {
mode = 0666
user = postfix
group = postfix
}
user = dovecot
}
service auth-worker {
user = vmail
}
service dict {
unix_listener dict {
}
} Dit is het hoofdconfiguratiebestand van dovecot.
Hier schakelen we onveilige verbindingen uit.
En schakelen we veilige verbindingen in.
Bestand «/etc/dovecot/conf.d/10-ssl.conf»
ssl = required
ssl_cert = < /etc/nginx/ssl/domain1.com.2018.chained.crt
ssl_key = < /etc/nginx/ssl/domain1.com.2018.key
local XX.XX.XX.X5 {
ssl_cert = < /etc/nginx/ssl/domain2.com.2018.chained.crt
ssl_key = < /etc/nginx/ssl/domain2.com.2018.key
}We configureren ssl. We geven aan dat ssl verplicht is.
En het certificaat zelf. Een belangrijk detail is de «local»-directive. Dit geeft aan welk ssl-certificaat moet worden gebruikt bij verbinding met welk lokaal IPv4.Overigens is IPv6 hier niet ingesteld, ik zal dat gemis later corrigeren.
XX.XX.XX.X5 (domain2) â er is geen certificaat. Voor clientverbindingen moet domain1.com worden opgegeven.
XX.XX.XX.X2 (domain3) â er is een certificaat, voor clientverbindingen kan domain1.com of domain3.com worden opgegeven.
Bestand «/etc/dovecot/conf.d/15-lda.conf»
protocol lda {
mail_plugins = $mail_plugins sieve
}Dit is later nodig voor spamassassin.
Bestand «/etc/dovecot/conf.d/20-imap.conf»
protocol imap {
mail_plugins = $mail_plugins antispam
}Dit is de antispam plugin. Het is nodig voor het trainen van spamassassin bij het verplaatsen naar/van de «Spam»-map.
Bestand «/etc/dovecot/conf.d/20-pop3.conf»
protocol pop3 {
}Gewoon zo'n bestand is er.
Bestand «/etc/dovecot/conf.d/20-lmtp.conf»
protocol lmtp {
mail_plugins = $mail_plugins sieve
postmaster_address = admin@domain1.com
}LMTP-configuratie.
Bestand «/etc/dovecot/conf.d/90-antispam.conf»
plugin {
antispam_backend = pipe
antispam_trash = Trash;trash
antispam_spam = Junk;Spam;SPAM
antispam_pipe_program_spam_arg = --spam
antispam_pipe_program_notspam_arg = --ham
antispam_pipe_program = /usr/bin/sa-learn
antispam_pipe_program_args = --username=%Lu
}Instellingen voor de training van SpamAssassin tijdens het verplaatsen van/naar de map «Spam».
Bestand «/etc/dovecot/conf.d/90-sieve.conf»
plugin {
sieve = ~/dovecot.sieve
sieve_dir = ~/sieve
sieve_after = /var/lib/dovecot/sieve/default.sieve
}Bestand waarin staat wat er met binnenkomende e-mails moet gebeuren.
Bestand «/var/lib/dovecot/sieve/default.sieve»
require ["fileinto", "mailbox"];
if header :contains "X-Spam-Flag" "YES" {
fileinto :create "Spam";
}Het moet worden gecompileerd: «sievec default.sieve».
Bestand «/etc/dovecot/conf.d/auth-sql.conf.ext»
passdb {
driver = sql
args = /etc/dovecot/dovecot-sql.conf.ext
}
userdb {
driver = static
args = uid=vmail gid=vmail home=/var/mail/vhosts/%d/%n
} Aanwijzing sql-bestanden voor authenticatie.
Het bestand zelf â als een manier van authenticatie.
Bestand «/etc/dovecot/dovecot-sql.conf.ext»
driver = mysql
connect = host=127.0.0.1 dbname=servermail user=usermail password=password
default_pass_scheme = SHA512-CRYPT
password_query = SELECT email as user, password FROM virtual_users WHERE email='%u';Dit komt overeen met de vergelijkbare instellingen voor postfix.
Bestand «/etc/dovecot/dovecot.conf»
protocols = imap lmtp pop3
listen = *, ::
dict {
}
!include conf.d/*.conf
!include_try local.conf Het belangrijkste configuratiebestand.
Belangrijk is dat we hier de protocollen opgeven/toevoegen.
============= SpamAssassin =============
apt-get install spamassassin spamcLaten we de pakketten installeren.
adduser spamd --disabled-loginWe voegen de gebruiker toe onder wiens naam.
systemctl enable spamassassin.serviceWe schakelen de automatische opstart van de SpamAssassin-service in bij het opstarten.
Bestand «/etc/default/spamassassin»:
CRON=1Automatische regelupdates «standaard» inschakelen.
Bestand «/etc/spamassassin/local.cf»:
report_safe 0
use_bayes 1
bayes_auto_learn 1
bayes_auto_expire 1
bayes_store_module Mail::SpamAssassin::BayesStore::MySQL
bayes_sql_dsn DBI:mysql:sa:localhost:3306
bayes_sql_username sa
bayes_sql_password passwordEen MySQL-database «sa» aanmaken met de gebruiker «sa» en het wachtwoord «password» (vervang door iets passends).
report_safe â in plaats van e-mail wordt er een rapport over de spam-e-mail verzonden.
use_bayes â dit zijn de instellingen voor machine learning van SpamAssassin.
De overige instellingen van SpamAssassin zijn eerder toegepast volgens het artikel.
.
.
.
.
============= Contact met de gemeenschap =============
Ik zou ook graag een idee in de gemeenschap willen gooien over hoe we de beveiliging van verzonden e-mails kunnen verbeteren. Aangezien ik zo diep in het onderwerp e-mail ben gedoken.
Zodat de gebruiker op zijn client (Outlook, Thunderbird, browserplugin, ...) een paar sleutels kan aanmaken. Een publieke en een privé. De publieke - verstuurd naar DNS. De privé - opgeslagen op de client. De mailservers zouden de publieke sleutel moeten kunnen toepassen om naar een specifieke ontvanger te verzenden.
En om spam te bestrijden bij dergelijke e-mails (ja, de mailserver kan de inhoud niet bekijken) - moeten er 3 regels worden ingevoerd:
- Verplichte geldige DKIM-handtekening, verplichte SPF, verplichte rDNS.
- Een neuraal netwerk voor het trainen van anti-spam + een database aan de clientzijde.
- Het encryptie-algoritme moet zodanig zijn dat de verzendende partij 100 keer meer CPU-kracht moet besteden aan het versleutelen dan de ontvangende partij.
Naast publieke e-mails moet er een standaard voor een voorstel-e-mail worden ontwikkeld om 'een beveiligde communicatie te starten'. Een van de gebruikers (e-mailadres) stuurt een e-mail naar een ander e-mailadres met een bijlage. In de e-mail staat een tekstvoorstel om een beveiligde communicatielijn te starten, met de publieke sleutel van de eigenaar van het e-mailadres (met de privé sleutel aan de clientzijde).
Je zou zelfs speciale sleutels voor elke communicatie kunnen maken. De ontvanger kan dit voorstel accepteren en zijn publieke sleutel terugsturen (die ook speciaal voor deze communicatie is gemaakt). Vervolgens verstuurt de eerste gebruiker een controlemail (versleuteld met de publieke sleutel van de tweede gebruiker) - bij ontvangst waarvan de tweede gebruiker de opgerichte communicatielijn als betrouwbaar kan beschouwen. Vervolgens verstuurt de tweede gebruiker een controlemail - en dan kan de eerste gebruiker de opgerichte lijn ook als beveiligd beschouwen.
Om te voorkomen dat sleutels onderweg worden onderschept, moet het protocol de mogelijkheid bieden om ten minste één publieke sleutel via een USB-stick te verzenden.
En het allerbelangrijkste - dat dit alles werkt (de vraag 'wie betaalt hiervoor?'):
Voer mailcertificaten in met prijzen vanaf 10$ voor 3 jaar. Deze certificaten stellen de verzender in staat om in de DNS aan te geven: 'mijn publieke sleutels bevinden zich daar'. Dit maakt het mogelijk om een beveiligde verbinding te starten en deze verbindingen gratis te accepteren.
Gmail begint eindelijk zijn gebruikers te monetariseren. Voor 10$ in 3 jaar krijgt men het recht om beveiligde communicatiekanalen te creëren.
============= Conclusie =============
Voor het testen van het hele artikel was ik van plan om een dedicated server voor een maand te huren en een domein met een SSL-certificaat aan te schaffen.
Maar door bepaalde levensomstandigheden heeft deze kwestie zich uitgesteld tot 2 maanden.
En nu, wanneer er weer tijd beschikbaar is, heb ik besloten om het artikel gewoon te publiceren zoals het is, en niet het risico te lopen dat de publicatie nog een jaar vertraging oploopt.
Als er genoeg vragen komen zoals 'dit is niet gedetailleerd genoeg beschreven', dan zal ik waarschijnlijk de middelen vinden om toch een dedicated server met een nieuw domein en een nieuw SSL-certificaat te nemen en het verder in detail te beschrijven, en belangrijker nog â alle gemiste belangrijke details aan het licht te brengen.
Ik zou ook graag feedback ontvangen over het idee van mailcertificaten. Als het idee in de smaak valt, zal ik proberen de middelen te vinden om een concept voor de RFC te schrijven.
Bij het kopiĂ«ren van grote delen van het artikel â geef een link naar dit artikel op.
Bij vertaling naar een andere taal â geef een link naar dit artikel op.
Ik zelf zal proberen om het in het Engels te vertalen en kruislinks toe te voegen.
Bron: habr.com
