Arch Post-Installation Checklist: Difference between revisions
m →Let's Encrypt: Added Automatic Renewal |
m Converted over to bc/hc/ic templates |
||
Line 1: | Line 1: | ||
= Passwords & User Creation = | = Passwords & User Creation = | ||
Make sure | Make sure {{ic|root}} has a password. | ||
Make sure you have a primary user set up. | Make sure you have a primary user set up. | ||
{{bc|1= | |||
# useradd -m -u <id -ge 1000> -g users -G wheel,games,video,audio,optical,storage,scanner,power <user> | |||
# passwd <user> | |||
}} | |||
= /etc/fstab = | = /etc/fstab = | ||
Line 12: | Line 14: | ||
= Time Zone = | = Time Zone = | ||
{{bc|1= | |||
# ln -sf /usr/share/zoneinfo/<region>/<city> /etc/localtime | |||
# hwclock --systohc | |||
}} | |||
= Localization = | = Localization = | ||
Un-comment your desired locales in | Un-comment your desired locales in {{ic|/etc/locale.conf}}, then run | ||
{{bc|locale-gen}} | |||
If you don't have the default | If you don't have the default {{ic|/etc/locale.gen}} file: | ||
{{bc|1= | |||
# rm /etc/locale.gen | |||
# pacman -Syu glibc | |||
}} | |||
Edit | Edit {{ic|/etc/locale.conf}} as you see fit | ||
{{hc|/etc/locale.conf|2= | |||
<nowiki>LANG=en_US.UTF-8 | |||
LANGUAGE=en_US | |||
LC_COLLATE=POSIX | |||
LC_MESSAGES=C | |||
LC_CTYPE=en_US.UTF-8 | |||
LC_NUMERIC=en_US.UTF-8 | |||
LC_TIME=en_US.UTF-8 | |||
LC_MONETARY=en_US.UTF-8 | |||
LC_PAPER=en_US.UTF-8 | |||
LC_NAME=en_US.UTF-8 | |||
LC_ADDRESS=en_US.UTF-8 | |||
LC_TELEPHONE=en_US.UTF-8 | |||
LC_MEASUREMENT=en_US.UTF-8 | |||
LC_IDENTIFICATION=en_US.UTF-8</nowiki> | |||
}} | |||
Set up | Set up {{ic|/etc/vconsole.conf}} with a keymap and (optionally) a font: | ||
{{hc|/etc/vconsole.conf|2= | |||
KEYMAP=us | |||
FONT=Lat2-Terminus16 | |||
}} | |||
= Initramfs = | = Initramfs = | ||
Line 52: | Line 62: | ||
Look for and edit the following lines: | Look for and edit the following lines: | ||
{{hc|/etc/mkinitcpio.conf|2= | |||
<nowiki>MODULES=([amdgpu|bochs_drm|cirrus|i915|nouveau|(nvidia nvidia_modeset nvidia_uvm nvidia_drm)] [ehci_pci usb_storage]>) | |||
HOOKS=(base udev autodetect modconf block [zfs] filesystems keyboard fsck [encrypt] keymap consolefont) | |||
COMPRESSION=lz4</nowiki> | |||
}} | |||
= Networking = | = Networking = | ||
Line 60: | Line 72: | ||
== Host Name == | == Host Name == | ||
Make sure a host name is set in | Make sure a host name is set in {{ic|/etc/hostname}} | ||
Then edit | Then edit {{ic|/etc/hosts}} | ||
{{hc|/etc/hosts|2= | |||
127.0.0.1 localhost.localdomain locahost | |||
::1 localhost.localdomain localhost | |||
127.0.1.1 <hostname>.localdomain <hostname> | |||
}} | |||
== Static Addressing == | == Static Addressing == | ||
Use | Use {{ic|systemd-networkd}} when a machine will use a static address without consulting a DHCP server. | ||
=== IPv4 Only === | === IPv4 Only === | ||
{{hc|/etc/systemd/network/network.network|2= | |||
[Match] | |||
MACAddress=<mac-address> | |||
[Network] | |||
Address=<ipv4-address>/<mask> | |||
DNS=<ipv4-address> | |||
Gateway=<ipv4-address> | |||
LinkLocalAddressing=no | |||
IPv6AcceptRA=no | |||
}} | |||
=== IPv4 & IPv6 === | === IPv4 & IPv6 === | ||
{{hc|/etc/systemd/network/network.network|2= | |||
[Match] | |||
MACAddress=<mac-address> | |||
[Network] | |||
Address=<ipv6-address>/<mask> | |||
DNS=<ipv6-address> | |||
Gateway=<ipv6-address> | |||
Address=<ipv4-address>/<mask> | |||
DNS=<ipv4-address> | |||
Gateway=<ipv4-address> | |||
}} | |||
=== Dynamic Addressing === | === Dynamic Addressing === | ||
It's preferable to use | It's preferable to use {{ic|connman}} or {{ic|Network Manager}} for dynamic addresses as {{ic|systemd-networkd}} doesn't play well with interfaces coming and going. | ||
If you'd rather use | If you'd rather use {{ic|systemd-networkd}} for DHCP: | ||
{{hc|/etc/systemd/network/network.network|2= | |||
[Match] | |||
MACAddress=<mac-address> | |||
[Network] | |||
DHCP=yes | |||
[DHCP] | |||
UseMTU=true | |||
}} | |||
== IPTables Firewall == | == IPTables Firewall == | ||
{{hc|/etc/iptables/iptables.rules|2= | |||
# SIMPLE STATEFUL FIREWALL | |||
*filter | |||
:INPUT DROP [0:0] | |||
:FORWARD DROP [0:0] | |||
:OUTPUT ACCEPT [100308:88697975] | |||
:TCP - [0:0] | |||
:UDP - [0:0] | |||
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT | |||
-A INPUT -i lo -j ACCEPT | |||
-A INPUT -p icmp -m icmp --icmp-type 8 -m conntrack --ctstate NEW -j ACCEPT | |||
-A INPUT -m conntrack --ctstate INVALID -j DROP | |||
-A INPUT -p udp -m conntrack --ctstate NEW -j UDP | |||
-A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j TCP | |||
-A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable | |||
-A INPUT -p tcp -j REJECT --reject-with tcp-reset | |||
-A INPUT -j REJECT --reject-with icmp-proto-unreachable | |||
# OPEN NECESSARY PORTS HERE | |||
-A TCP -p tcp -m tcp --dport 22 -j ACCEPT -m comment --comment "ssh" | |||
-A TCP -p tcp -m tcp --dport 80 -j ACCEPT -m comment --comment "http" | |||
-A TCP -p tcp -m tcp --dport 443 -j ACCEPT -m comment --comment "https" | |||
-A TCP -p tcp -m tcp --dport 465 -j ACCEPT -m comment --comment "smtp secure" | |||
-A TCP -p tcp -m tcp --dport 873 -j ACCEPT -m comment --comment "rsync" | |||
-A TCP -p tcp -m tcp --dport 993 -j ACCEPT -m comment --comment "imap secure" | |||
-A TCP -p tcp -m tcp --dport 3000 -j ACCEPT -m comment --comment "cryptpad http" | |||
-A TCP -p tcp -m tcp --dport 3001 -j ACCEPT -m comment --comment "cryptpad safe http" | |||
-A TCP -p tcp -m tcp --dport 64738 -j ACCEPT -m comment --comment "mumble tcp" | |||
-A UDP -p udp -m udp --dport 64738 -j ACCEPT -m comment --comment "mumble udp" | |||
COMMIT | |||
}} | |||
= Pacman = | = Pacman = | ||
Line 145: | Line 166: | ||
== Mirror List == | == Mirror List == | ||
Install and use | Install and use {{ic|reflector}} to automate the use and selection of mirrors. | ||
{{bc|1= | |||
# pacman -Syu reflector | |||
# reflector -c <country> -p https -l 5 --sort rate --save /etc/pacman.d/mirrorlist | |||
}} | |||
== General Utilities == | == General Utilities == | ||
{{bc|# pacman -Syu --needed git rsync openssh}} | |||
== E-mail == | == E-mail == | ||
{{bc|# pacman -Syu --needed dovecot postfix rspamd swaks}} | |||
== Nginx Web Server and Reverse Proxy == | == Nginx Web Server and Reverse Proxy == | ||
{{bc|# pacman -Syu --needed ca-certificates certbot-nginx mariadb nginx php-fpm}} | |||
== Roundcube Web Mail == | == Roundcube Web Mail == | ||
{{bc|# pacman -Syu --needed pigeonhole roundcube}} | |||
= SSH Setup = | = SSH Setup = | ||
Look for and edit the following lines in | Look for and edit the following lines in {{ic|/etc/ssh/sshd_config}}: | ||
{{hc|/etc/ssh/ssd_config|2= | |||
<nowiki>Port <port> | |||
AddressFamily <any|inet|inet6> | |||
ListenAddress <ip4-address> | |||
ListenAddress <ip6-address> | |||
LogLevel VERBOSE | |||
PermitRootLogin prohibit-password | |||
PubkeyAuthentication yes | |||
PasswordAuthentication no | |||
PermitEmptyPasswords no | |||
ChallengeResponseAuthentication no | |||
UsePAM yes | |||
AllowUsers <space-separated-list-of-users> | |||
AllowAgentForwarding no | |||
AllowTcpForwarding no</nowiki> | |||
}} | |||
Then make sure the {{ic|sshd}} service is enabled and running: | |||
{{bc|# systemctl enable --now sshd}} | |||
= PHP-FPM = | = PHP-FPM = | ||
Look for and edit the following lines in | Look for and edit the following lines in {{ic|/etc/php/php.ini}}: | ||
{{hc|/etc/php/php.ini|2= | |||
[PHP] | |||
open_basedir = /srv/http/:/home/:/tmp/:/usr/share/pear/:/usr/share/webapps/:/dev/urandom:/proc/meminfo | |||
include_path = ".:/php/includes:/usr/share/pear" | |||
upload_max_filesize = 8M | |||
extension=apcu | |||
extension=dba | |||
extension=exif | |||
extension=gd | |||
extension=gettext | |||
extension=iconv | |||
extension=intl | |||
extension=sodium | |||
extension=ldap | |||
extension=mysqli | |||
zend_extension=opcache | |||
extension=pdo_mysql | |||
extension=soap | |||
[Pdo_mysql] | |||
pdo_mysql.cache_size = 2000 | |||
[Session] | |||
session.save_path = "/tmp/php/sessions" | |||
[opcache] | |||
opcache.enable=1 | |||
opcache.enable_cli=1 | |||
opcache.memory_consumption=128 | |||
opcache.interned_strings_buffer=8 | |||
opcache.max_accelerated_files=10000 | |||
opcache.revalidate_freq=1 | |||
opcache.save_comments=1 | |||
}} | |||
Then make sure the {{ic|php-fpm}} service is enabled and running: | |||
{{bc|# systemctl enable --now php-fpm}} | |||
= Nginx = | = Nginx = | ||
First, edit < | First, edit {{ic|/etc/nginx/nginx.conf}}: | ||
{{hc|/etc/nginx/nginx.conf|2= | |||
<nowiki>user http; | |||
worker_processes 1; # one(1) worker or equal the number of _real_ cpu cores. 4=4 core cpu | |||
worker_priority 15; # renice workers to reduce priority compared to system processes for machine health. Worst case nginx will get ~25% system resources at nice=15 | |||
worker_rlimit_nofile 1024; # maximum number of open files | |||
worker_cpu_affinity auto; | |||
events { | |||
multi_accept on; | |||
accept_mutex on; # serially accept() connections and pass to workers, efficient if workers gt 1 | |||
accept_mutex_delay 500ms; # worker process will accept mutex after this delay if not assigned. (default 500ms) | |||
worker_connections 1024; # number of parallel or concurrent connections per worker_processes | |||
} | |||
http { | |||
charset utf-8; | |||
aio on; # asynchronous file I/O, fast with ZFS, make sure sendfile=off | |||
sendfile off; # on for decent direct disk IO, off for VMs | |||
tcp_nopush off; # turning on requires sendfile=on | |||
tcp_nodelay on; # Nagle buffering algorithm, used for keepalive only | |||
server_tokens off; # version number in error pages | |||
log_not_found off; | |||
types_hash_max_size 4096; | |||
# MIME | |||
include mime.types; | |||
default_type application/octet-stream; | |||
# logging | |||
access_log /var/log/nginx/access.log; | |||
error_log /var/log/nginx/error.log warn; | |||
# SSL | |||
ssl_session_timeout 1440m; | |||
ssl_session_cache shared:le_nginx_SSL:10m; | |||
ssl_session_tickets off; | |||
ssl_prefer_server_ciphers off; | |||
# Diffie-Hellman parameter for DHE ciphersuites | |||
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; | |||
# Mozilla Intermediate configuration | |||
ssl_protocols TLSv1.2 TLSv1.3; | |||
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; | |||
# OCSP Stapling | |||
ssl_stapling on; | |||
ssl_stapling_verify on; | |||
resolver 1.1.1.1 1.0.0.1 8.8.8.8 8.8.4.4 208.67.222.222 208.67.220.220 valid=60s; | |||
resolver_timeout 2s; | |||
# Size Limits | |||
#client_body_buffer_size 8k; | |||
#client_header_buffer_size 1k; | |||
client_max_body_size 16M; | |||
#large_client_header_buffers 4 4k/8k; | |||
## From StackOverflow: for "upstream sent too big header while reading response header from upstream" | |||
fastcgi_buffers 8 16k; | |||
fastcgi_buffer_size 32k; | |||
# Timeouts, do not keep connections open longer then necessary to reduce | |||
# resource usage and deny Slowloris type attacks. | |||
client_body_timeout 5s; # maximum time between packets the client can pause when sending nginx any data | |||
client_header_timeout 5s; # maximum time the client has to send the entire header to nginx | |||
keepalive_timeout 75s; # timeout which a single keep-alive client connection will stay open | |||
send_timeout 15s; # maximum time between packets nginx is allowed to pause when sending the client data | |||
## General Options | |||
gzip off; # disable on the fly gzip compression due to higher latency, only use gzip_static | |||
#gzip_http_version 1.0; # serve gzipped content to all clients including HTTP/1.0 | |||
gzip_static on; # precompress content (gzip -9) with an external script | |||
#gzip_vary on; # send response header "Vary: Accept-Encoding" | |||
gzip_proxied any; # allows compressed responses for any request even from proxies | |||
ignore_invalid_headers on; | |||
keepalive_requests 50; # number of requests per connection, does not affect SPDY | |||
keepalive_disable none; # allow all browsers to use keepalive connections | |||
max_ranges 1; # allow a single range header for resumed downloads and to stop large range header DoS attacks | |||
msie_padding off; | |||
open_file_cache max=1000 inactive=2h; | |||
open_file_cache_errors on; | |||
open_file_cache_min_uses 1; | |||
open_file_cache_valid 1h; | |||
output_buffers 1 512; | |||
postpone_output 1440; # postpone sends to match our machine's MSS | |||
read_ahead 512K; # kernel read head set to the output_buffers | |||
recursive_error_pages on; | |||
reset_timedout_connection on; # reset timed out connections freeing ram | |||
server_name_in_redirect off; # if off, nginx will use the requested Host header | |||
source_charset utf-8; # same value as "charset" | |||
## Request limits | |||
limit_req_zone $binary_remote_addr zone=gulag:1m rate=60r/m; | |||
## Log Format | |||
log_format main '$remote_addr $host $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $ssl_cipher $request_time'; | |||
# load configs | |||
include /etc/nginx/conf.d/*.conf; | |||
include /etc/nginx/sites-enabled/*.conf; | |||
}</nowiki> | |||
}} | |||
Make the | Make the {{ic|sites-available}} and {{ic|sites-enabled}} directories. | ||
{{bc|# mkdir /etc/nginx/sites-<nowiki>{available,enabled}</nowiki>}} | |||
Then make a site available by creating | Then make a site available by creating {{ic|/etc/nginx/sites-available/<domain>.conf}}:<br/> | ||
(Remove the | (Remove the {{ic|#}} after setting up Let's Encrypt.) | ||
< | {{hc|/etc/nginx/sites-available/<donmain>.conf|2= | ||
<nowiki>server { | |||
listen 80; | listen 80; | ||
listen [::]:80; | listen [::]:80; | ||
Line 426: | Line 455: | ||
} | } | ||
}</ | }</nowiki> | ||
}} | |||
Enable the site | Enable the site | ||
{{bc|# ln -s ../sites-available/<domain>.conf /etc/nginx/sites-enabled/<domain>.conf}} | |||
Then create | Then create {{ic|index.php}} for your new site. | ||
< | {{hc|/srv/http/<domain>/index.php|2= | ||
<nowiki><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> | |||
<html xmlns="http://www.w3.org/1999/xhtml"> | <html xmlns="http://www.w3.org/1999/xhtml"> | ||
<head> | <head> | ||
Line 450: | Line 481: | ||
</body> | </body> | ||
</html></ | </html></nowiki> | ||
}} | |||
Finally, make sure the | Finally, make sure the {{ic|nginx}} service is enabled and running: | ||
{{bc|# systemctl enable --now nginx}} | |||
= Let's Encrypt = | = Let's Encrypt = |
Revision as of 09:55, 7 November 2019
Passwords & User Creation
Make sure root
has a password.
Make sure you have a primary user set up.
# useradd -m -u <id -ge 1000> -g users -G wheel,games,video,audio,optical,storage,scanner,power <user> # passwd <user>
/etc/fstab
Time Zone
# ln -sf /usr/share/zoneinfo/<region>/<city> /etc/localtime # hwclock --systohc
Localization
Un-comment your desired locales in /etc/locale.conf
, then run
locale-gen
If you don't have the default /etc/locale.gen
file:
# rm /etc/locale.gen # pacman -Syu glibc
Edit /etc/locale.conf
as you see fit
/etc/locale.conf
LANG=en_US.UTF-8 LANGUAGE=en_US LC_COLLATE=POSIX LC_MESSAGES=C LC_CTYPE=en_US.UTF-8 LC_NUMERIC=en_US.UTF-8 LC_TIME=en_US.UTF-8 LC_MONETARY=en_US.UTF-8 LC_PAPER=en_US.UTF-8 LC_NAME=en_US.UTF-8 LC_ADDRESS=en_US.UTF-8 LC_TELEPHONE=en_US.UTF-8 LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=en_US.UTF-8
Set up /etc/vconsole.conf
with a keymap and (optionally) a font:
/etc/vconsole.conf
KEYMAP=us FONT=Lat2-Terminus16
Initramfs
Look for and edit the following lines:
/etc/mkinitcpio.conf
MODULES=([amdgpu|bochs_drm|cirrus|i915|nouveau|(nvidia nvidia_modeset nvidia_uvm nvidia_drm)] [ehci_pci usb_storage]>) HOOKS=(base udev autodetect modconf block [zfs] filesystems keyboard fsck [encrypt] keymap consolefont) COMPRESSION=lz4
Networking
Host Name
Make sure a host name is set in /etc/hostname
Then edit /etc/hosts
/etc/hosts
127.0.0.1 localhost.localdomain locahost ::1 localhost.localdomain localhost 127.0.1.1 <hostname>.localdomain <hostname>
Static Addressing
Use systemd-networkd
when a machine will use a static address without consulting a DHCP server.
IPv4 Only
/etc/systemd/network/network.network
[Match] MACAddress=<mac-address> [Network] Address=<ipv4-address>/<mask> DNS=<ipv4-address> Gateway=<ipv4-address> LinkLocalAddressing=no IPv6AcceptRA=no
IPv4 & IPv6
/etc/systemd/network/network.network
[Match] MACAddress=<mac-address> [Network] Address=<ipv6-address>/<mask> DNS=<ipv6-address> Gateway=<ipv6-address> Address=<ipv4-address>/<mask> DNS=<ipv4-address> Gateway=<ipv4-address>
Dynamic Addressing
It's preferable to use connman
or Network Manager
for dynamic addresses as systemd-networkd
doesn't play well with interfaces coming and going.
If you'd rather use systemd-networkd
for DHCP:
/etc/systemd/network/network.network
[Match] MACAddress=<mac-address> [Network] DHCP=yes [DHCP] UseMTU=true
IPTables Firewall
/etc/iptables/iptables.rules
# SIMPLE STATEFUL FIREWALL *filter :INPUT DROP [0:0] :FORWARD DROP [0:0] :OUTPUT ACCEPT [100308:88697975] :TCP - [0:0] :UDP - [0:0] -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -A INPUT -i lo -j ACCEPT -A INPUT -p icmp -m icmp --icmp-type 8 -m conntrack --ctstate NEW -j ACCEPT -A INPUT -m conntrack --ctstate INVALID -j DROP -A INPUT -p udp -m conntrack --ctstate NEW -j UDP -A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j TCP -A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable -A INPUT -p tcp -j REJECT --reject-with tcp-reset -A INPUT -j REJECT --reject-with icmp-proto-unreachable # OPEN NECESSARY PORTS HERE -A TCP -p tcp -m tcp --dport 22 -j ACCEPT -m comment --comment "ssh" -A TCP -p tcp -m tcp --dport 80 -j ACCEPT -m comment --comment "http" -A TCP -p tcp -m tcp --dport 443 -j ACCEPT -m comment --comment "https" -A TCP -p tcp -m tcp --dport 465 -j ACCEPT -m comment --comment "smtp secure" -A TCP -p tcp -m tcp --dport 873 -j ACCEPT -m comment --comment "rsync" -A TCP -p tcp -m tcp --dport 993 -j ACCEPT -m comment --comment "imap secure" -A TCP -p tcp -m tcp --dport 3000 -j ACCEPT -m comment --comment "cryptpad http" -A TCP -p tcp -m tcp --dport 3001 -j ACCEPT -m comment --comment "cryptpad safe http" -A TCP -p tcp -m tcp --dport 64738 -j ACCEPT -m comment --comment "mumble tcp" -A UDP -p udp -m udp --dport 64738 -j ACCEPT -m comment --comment "mumble udp" COMMIT
Pacman
Mirror List
Install and use reflector
to automate the use and selection of mirrors.
# pacman -Syu reflector # reflector -c <country> -p https -l 5 --sort rate --save /etc/pacman.d/mirrorlist
General Utilities
# pacman -Syu --needed git rsync openssh
# pacman -Syu --needed dovecot postfix rspamd swaks
Nginx Web Server and Reverse Proxy
# pacman -Syu --needed ca-certificates certbot-nginx mariadb nginx php-fpm
Roundcube Web Mail
# pacman -Syu --needed pigeonhole roundcube
SSH Setup
Look for and edit the following lines in /etc/ssh/sshd_config
:
/etc/ssh/ssd_config
Port <port> AddressFamily <any|inet|inet6> ListenAddress <ip4-address> ListenAddress <ip6-address> LogLevel VERBOSE PermitRootLogin prohibit-password PubkeyAuthentication yes PasswordAuthentication no PermitEmptyPasswords no ChallengeResponseAuthentication no UsePAM yes AllowUsers <space-separated-list-of-users> AllowAgentForwarding no AllowTcpForwarding no
Then make sure the sshd
service is enabled and running:
# systemctl enable --now sshd
PHP-FPM
Look for and edit the following lines in /etc/php/php.ini
:
/etc/php/php.ini
[PHP] open_basedir = /srv/http/:/home/:/tmp/:/usr/share/pear/:/usr/share/webapps/:/dev/urandom:/proc/meminfo include_path = ".:/php/includes:/usr/share/pear" upload_max_filesize = 8M extension=apcu extension=dba extension=exif extension=gd extension=gettext extension=iconv extension=intl extension=sodium extension=ldap extension=mysqli zend_extension=opcache extension=pdo_mysql extension=soap [Pdo_mysql] pdo_mysql.cache_size = 2000 [Session] session.save_path = "/tmp/php/sessions" [opcache] opcache.enable=1 opcache.enable_cli=1 opcache.memory_consumption=128 opcache.interned_strings_buffer=8 opcache.max_accelerated_files=10000 opcache.revalidate_freq=1 opcache.save_comments=1
Then make sure the php-fpm
service is enabled and running:
# systemctl enable --now php-fpm
Nginx
First, edit /etc/nginx/nginx.conf
:
/etc/nginx/nginx.conf
user http; worker_processes 1; # one(1) worker or equal the number of _real_ cpu cores. 4=4 core cpu worker_priority 15; # renice workers to reduce priority compared to system processes for machine health. Worst case nginx will get ~25% system resources at nice=15 worker_rlimit_nofile 1024; # maximum number of open files worker_cpu_affinity auto; events { multi_accept on; accept_mutex on; # serially accept() connections and pass to workers, efficient if workers gt 1 accept_mutex_delay 500ms; # worker process will accept mutex after this delay if not assigned. (default 500ms) worker_connections 1024; # number of parallel or concurrent connections per worker_processes } http { charset utf-8; aio on; # asynchronous file I/O, fast with ZFS, make sure sendfile=off sendfile off; # on for decent direct disk IO, off for VMs tcp_nopush off; # turning on requires sendfile=on tcp_nodelay on; # Nagle buffering algorithm, used for keepalive only server_tokens off; # version number in error pages log_not_found off; types_hash_max_size 4096; # MIME include mime.types; default_type application/octet-stream; # logging access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log warn; # SSL ssl_session_timeout 1440m; ssl_session_cache shared:le_nginx_SSL:10m; ssl_session_tickets off; ssl_prefer_server_ciphers off; # Diffie-Hellman parameter for DHE ciphersuites ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # Mozilla Intermediate configuration ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; # OCSP Stapling ssl_stapling on; ssl_stapling_verify on; resolver 1.1.1.1 1.0.0.1 8.8.8.8 8.8.4.4 208.67.222.222 208.67.220.220 valid=60s; resolver_timeout 2s; # Size Limits #client_body_buffer_size 8k; #client_header_buffer_size 1k; client_max_body_size 16M; #large_client_header_buffers 4 4k/8k; ## From StackOverflow: for "upstream sent too big header while reading response header from upstream" fastcgi_buffers 8 16k; fastcgi_buffer_size 32k; # Timeouts, do not keep connections open longer then necessary to reduce # resource usage and deny Slowloris type attacks. client_body_timeout 5s; # maximum time between packets the client can pause when sending nginx any data client_header_timeout 5s; # maximum time the client has to send the entire header to nginx keepalive_timeout 75s; # timeout which a single keep-alive client connection will stay open send_timeout 15s; # maximum time between packets nginx is allowed to pause when sending the client data ## General Options gzip off; # disable on the fly gzip compression due to higher latency, only use gzip_static #gzip_http_version 1.0; # serve gzipped content to all clients including HTTP/1.0 gzip_static on; # precompress content (gzip -9) with an external script #gzip_vary on; # send response header "Vary: Accept-Encoding" gzip_proxied any; # allows compressed responses for any request even from proxies ignore_invalid_headers on; keepalive_requests 50; # number of requests per connection, does not affect SPDY keepalive_disable none; # allow all browsers to use keepalive connections max_ranges 1; # allow a single range header for resumed downloads and to stop large range header DoS attacks msie_padding off; open_file_cache max=1000 inactive=2h; open_file_cache_errors on; open_file_cache_min_uses 1; open_file_cache_valid 1h; output_buffers 1 512; postpone_output 1440; # postpone sends to match our machine's MSS read_ahead 512K; # kernel read head set to the output_buffers recursive_error_pages on; reset_timedout_connection on; # reset timed out connections freeing ram server_name_in_redirect off; # if off, nginx will use the requested Host header source_charset utf-8; # same value as "charset" ## Request limits limit_req_zone $binary_remote_addr zone=gulag:1m rate=60r/m; ## Log Format log_format main '$remote_addr $host $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $ssl_cipher $request_time'; # load configs include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*.conf; }
Make the sites-available
and sites-enabled
directories.
# mkdir /etc/nginx/sites-{available,enabled}
Then make a site available by creating /etc/nginx/sites-available/<domain>.conf
:
(Remove the #
after setting up Let's Encrypt.)
/etc/nginx/sites-available/<donmain>.conf
server { listen 80; listen [::]:80; server_name <domain>; root /srv/http/$host; index index.html index.php; # if ($host = <domain>) { # return 301 https://$host$request_uri; # } # # return 404; # #} # #server { # # listen 443 ssl http2; # listen [::]:443 ssl http2; # server_name <domain>; # root /srv/http/$host; # index index.html index.php; # # ssl_certificate /etc/letsencrypt/live/<domain>/fullchain.pem; # ssl_certificate_key /etc/letsencrypt/live/<domain>/privkey.pem; # ssl_trusted_certificate /etc/letsencrypt/live/<domain>/chain.pem; # # fastcgi_param HTTPS on; # # add_header Strict-Transport-Security max-age=15768000; add_header Cache-Control "public"; add_header X-Frame-Options "DENY"; access_log /var/log/nginx/access.log main buffer=32k; error_log /var/log/nginx/error.log error; limit_req zone=gulag burst=200 nodelay; # ACME challenge location ^~ /.well-known { allow all; alias /var/lib/letsencrypt/$host/.well-known; default_type "text/plain"; try_files $uri =404; } location ~ /(data|conf|bin|inc)/ { deny all; } # static file 404's are strict access by hostname aren't logged and expires header is set to maximum age location ~* \.(jpg|jpeg|gif|css|png|js|ico|html)$ { access_log off; expires max; } location ~ \.php$ { try_files $uri = 404; fastcgi_pass unix:/run/php-fpm/php-fpm.sock; fastcgi_index index.php; include fastcgi.conf; } location ~ \.php5$ { try_files $uri = 404; fastcgi_pass unix:/run/php-fpm/php-fpm.sock; fastcgi_index index.php5; include fastcgi.conf; } location ~ /\.ht { deny all; } }
Enable the site
# ln -s ../sites-available/<domain>.conf /etc/nginx/sites-enabled/<domain>.conf
Then create index.php
for your new site.
/srv/http/<domain>/index.php
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Server Configuration Confirmation</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> </head> <body style="font-family:sans-serif;"> <h1>Web server is properly configured!</h1> <?php echo "<h2>PHP is properly configured as well!</h2>" ?> <p>Time to add some content!</p> </body> </html>
Finally, make sure the nginx
service is enabled and running:
# systemctl enable --now nginx
Let's Encrypt
# certbot --nginx
The nginx
plugin will guide you and help automate the process.
Take note that the nginx
configuration in this guide takes into account the settings suggested by certbot
.
Automatic Renewal
These will automatically renew your certificates every 2 months on the first Sunday of the month at 4am.
Systemd
/etc/systemd/system/certbot.service
[Unit] Description=Let's Encrypt renewal [Service] Type=oneshot ExecStart=/usr/bin/certbot renew --quiet --agree-tos
/etc/systemd/system/certbot.timer
[Unit] Description=Twice daily renewal of Let's Encrypt's certificates [Timer] OnCalendar=Sun *-2/12-1..7 04:00:00 RandomizedDelaySec=1h Persistent=true [Install] WantedBy=timers.target
Crontab
0 4 1-7 2-12/2 0 /usr/bin/certbot renew