A presentation by Justin Mayer
Twitter: @jmayer
Design and build web and mobile products
Obscene 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)
echo 'UseRoaming no' | sudo tee -a /etc/ssh/ssh_config
“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"
Disk/partition vs. directory in existing FS
Popular examples: LUKS vs. EncFS
Kernelspace
Encrypts whole block devices
Operates below filesystem layer
Content can be filesystem, partition table, LVM
Userspace (via FUSE)
Encrypts files
Adds layer to existing filesystem
Simple: can sometimes just check a box
Least intrusive
Don't need to be root
Password entry can occur during/after login
Fewer directories are encrypted
File metadata not encrypted
Can't encrypt swap
Performance
Entire disk is encrypted
Metadata is encrypted
Swap can be encrypted
Better performance for some use cases
Much harder to set up
Password entry must occur at boot time
Much harder than it should be
Two-step authorization via mobile?
“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-
Confidentiality
Integrity
Identity
apache/nginx
standalone
webroot
manual
DNS-01
git clone https://github.com/letsencrypt/letsencrypt
cd letsencrypt; ./letsencrypt-auto
sudo letsencrypt --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 to come
https://scotthelme.co.uk/hsts-the-missing-link-in-tls/
# 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:50m;
ssl_session_timeout 1d;
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
https://scotthelme.co.uk/tag/csp/
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';