Deploy your application without getting owned
A presentation by Justin Mayer (@jmayer)
Design and build web and mobile products
Unreasonable amount of my time is spent on security
Focus is on low-hanging fruit
Figure out what works best for you
You are a security professional
There is no menu of choices
“Safer” not to upgrade automatically
Debian / Ubuntu:
apt-get install unattended-upgrades
Red Hat (recent):
dnf -y install dnf-automatic
You think you are covered
Debian: Create /etc/apt/apt.conf.d/20auto-upgrades
:
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
Create /etc/dnf/automatic.conf
:
upgrade_type = security
apply_updates = yes
Enable and start automatic updates via:
systemctl enable dnf-automatic.timer
systemctl start dnf-automatic.timer
Kernel updates require a reboot to take effect
How do you know when that is? (when you log in)
“This stuff is complicated and
badly documented and
doesn’t really work great.”
/etc/ssh/ssh_config
:
Host *
PasswordAuthentication no
ChallengeResponseAuthentication no
UseRoaming no
PubkeyAuthentication yes
HostKeyAlgorithms ssh-ed25519-cert-v01@openssh.com,ssh-ed25519
KexAlgorithms curve25519-sha256@libssh.org
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,
aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,
hmac-ripemd160-etm@openssh.com,umac-128-etm@openssh.com,
hmac-sha2-512,hmac-sha2-256,hmac-ripemd160,umac-128@openssh.com
~/.ssh/config
:
Host *
IdentitiesOnly yes
IdentityFile ~/.ssh/id_ed25519
# Fall back to lesser security where necessary
Host bitbucket.org github.com
HostKeyAlgorithms ssh-ed25519-cert-v01@openssh.com,ssh-ed25519,ssh-rsa-cert-v01@openssh.com,ssh-rsa
KexAlgorithms curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256
IdentityFile ~/.ssh/id_rsa
/etc/ssh/sshd_config
:
Host *
HostKey /etc/ssh/ssh_host_ed25519_key
# Only if you need it:
#HostKey /etc/ssh/ssh_host_rsa_key
PermitRootLogin no
Good resources:
https://stribika.github.io/2015/01/04/secure-secure-shell.html
https://blog.0xbadc0de.be/archives/300
1024-bit DSA keys used to be the norm
Schedule periodic reviews
Rotate your keys
Scans log files for malicious signs
Update firewall to reject bad actor IP addresses
… or any other arbitrary action
Ban SSH login abusers via /etc/fail2ban/jail.local
:
[DEFAULT]
ignoreip = 127.0.0.1 64.32.16.192/27 192.168.50.0/24
bantime = 3600
maxretry = 3
[ssh]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
[ssh-ddos]
enabled = true
port = ssh
bantime = 172800
Apache / Nginx
FTP
(please don't use FTP)
Scans for rootkits, backdoors, other exploits
Compares hashes of important files with known good ones
Install via: apt-get install rkhunter libwww-perl
Have apt inform rkhunter of new packages…
… by ensuring /etc/default/rkhunter
contains:
APT_AUTOGEN="true"
Configure rkhunter via /etc/rkhunter.conf.local
:
ALLOWHIDDENDIR="/etc/.hg"
ALLOWHIDDENDIR="/etc/.java"
ALLOWHIDDENDIR="/dev/.udev"
ALLOWHIDDENFILE="/etc/.hgignore"
ALLOWHIDDENFILE="/dev/.blkid.tab"
ALLOWHIDDENFILE="/dev/.blkid.tab.old"
“I’m a back-end developer”
Do you build REST APIs?
Then you need to deal with web security
Bank 1 D-
Bank 2 D-
Bank 3 D-
Bank 4 D-
Health insurance company D
Popular e-commerce site D-
apache/nginx
standalone
webroot
manual
DNS-01
git clone https://github.com/certbot/certbot
cd certbot; ./certbot-auto
sudo certbot --email name@example.com --domains monitorial.com --text \
--agree-eula --agree-tos --debug --verbose --authenticator standalone auth
ssl_certificate /etc/letsencrypt/live/monitorial.com/fullcert.pem;
ssl_certificate_key /etc/letsencrypt/live/monitorial.com/privkey.pem;
acme-tiny
simp_le
lego
dokku-letsencrypt
… and tons more
https://www.owasp.org/index.php/HTTP_Strict_Transport_Security
# HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
add_header Strict-Transport-Security "max-age=15768000; includeSubdomains;";
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
ssl_session_cache shared:SSL:5m;
ssl_session_timeout 1h;
ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
https://www.maxcdn.com/one/visual-glossary/ocsp-stapling/
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
# Specifying resolver is optional; will use system DNS resolution if not specified
ssl_trusted_certificate /etc/letsencrypt/live/monitorial.com/chain.pem;
“I think for a site of any complexity at all, you need to build for CSP from the very beginning.”
add_header Content-Security-Policy:
"default-src 'self';
script-src https://cdnjs.cloudflare.com:443 https://secure.gaug.es:443;
img-src https://i.imgur.com:443";
unsafe-inline
openssl genrsa -out monitorial-b1.key 4096
openssl req -new -key monitorial-b1.key -sha256 -out monitorial-b1.csr
openssl genrsa -out monitorial-b2.key 4096
openssl req -new -key monitorial-b2.key -sha256 -out monitorial-b2.csr
openssl x509 -pubkey < monitorial.crt | openssl pkey -pubin -outform der | \
openssl dgst -sha256 -binary | base64
openssl req -pubkey < monitorial-b1.csr | openssl pkey -pubin -outform der | \
openssl dgst -sha256 -binary | base64
openssl req -pubkey < monitorial-b2.csr | openssl pkey -pubin -outform der | \
openssl dgst -sha256 -binary | base64
add_header Public-Key-Pins \
'pin-sha256="iv0dWv985sPcJUb9vy6c06iO2FAkQOrJy60wkcWQ4h7="; \
pin-sha256="Dwc7KK2muQoMjMg5qosU5zLM2N4sjdUFLU1dELDDzSJ="; \
pin-sha256="UkpY0KkzEsNQC7Yzp8iDSTHarD3BPzlVptNkDPBgODG="; \
max-age=10';
OCSP stapling
TLS extension (e.g., nginx-ct
)
x.509v3 extension