(Updated June 30, 2025)
There are a variety of Ubuntu hardening techniques out there. These are just a few that should be of interest.
Secure shared memory
Shared memory can be used as an attack vector for running services.
Edit the /etc/fstab
file and add the following to the bottom:
tmpfs /run/shm tmpfs defaults,noexec,nosuid 0 0
A reboot is needed to make the change.
Secure ssh login for specific users
Although you can secure a server with a firewall, sometimes the server simply must be accessible to certain users, even if a VPN is an option. You may also want to make it certain users from certain networks.
The /etc/ssh/sshd_config
file has the configuration of sshd. Edit the /etc/ssh/sshd_config
file and add a line like:
AllowUsers student@192.168.2.28
To make the change:
service ssh restart
Note that this only allows student
from the IP 192.168.2.28
. Anyone else will be denied, even if the credentials are correct.
If you wanted to allow everyone from the same subnet, you could do
AllowUsers *@192.168.2.*
or consider other modifications:
AllowUsers *@192.168.2.0/24 *@*.example.com AllowGroups ssh
Keep in mind that any changes require a restart of the ssh service.
Login Banner
Once upon a time, Unixes used the /etc/motd
file to provide the Message Of The Day as the method by which users were greeted upon login. It also became a vehicle for additional information. Today, the MOTD is more robust and Linuxes are using a more dynamic MOTD model including Ubuntu.
The majority of the details provided by this dynamic often center around available patches, system utilization and general heatlh of the system.
Many banners greet the user with a “Welcome” message. This should never be allowed. Rather, systems should provide policy information regarding the legal ramifications of illegal access to and the use and modification of a system to which they are connected.
Create a new MOTD file something like /etc/policy.motd
Find the lines in /etc/pam.d/sshd
that look like:
session optional pam_motd.so motd=/run/motd.dynamic session optional pam_motd.so noupdate
and comment them out by putting #’s at the beginning of the line.
# session optional pam_motd.so motd=/run/motd.dynamic # session optional pam_motd.so noupdate
Edit /etc/ssh/sshd_config
and modify the Banner
option to look like:
Banner /etc/policy.motd
Remember to restart the ssh service.
The network layer
The network configuration can be further tweaked to prevent source routing, ignore redirects, block SYN attacks and ignore pings. You can also log malformed IPs.
Edit the /etc/sysctl.conf
file adding the following:
### ### SYSTEM SECURITY ### ### # Enable address Space Randomization kernel.randomize_va_space = 2 # Restrict core dumps fs.suid_dumpable = 0 # Hide kernel pointers kernel.kptr_restrict = 1 # Restrict access to kernel logs kernel.dmesg_restrict = 1 # Restrict ptrace scope kernel.yama.ptrace_scope = 1 # Protect links on the filesystem fs.protected_hardlinks = 1 fs.protected_symlinks = 1 ### ### IMPROVE SYSTEM MEMORY MANAGEMENT ### ### # Increase size of file handles and inode cache fs.file-max = 209708 # Do less swapping vm.swappiness = 30 vm.dirty_ratio = 30 vm.dirty_background_ratio = 5 # specifies the minimum virtual address that a process is allowed to mmap vm.mmap_min_addr = 4096 # 50% overcommitment of available memory vm.overcommit_ratio = 50 vm.overcommit_memory = 0 # Set maximum amount of memory allocated to shm to 256MB kernel.shmmax = 268435456 kernel.shmall = 268435456 # Keep at least 64MB of free RAM space available vm.min_free_kbytes = 65535 ### ### Deprecated/Not-in-use keys for security ### # The contents of /proc//maps and smaps files are only visible to # readers that are allowed to ptrace() the process # kernel.maps_protect = 1 # Enable ExecShield # kernel.exec-shield = 1 ### ### NETWORK SECURITY ### ### # Do not allow unprivileged users to run code in the kernel through BPF kernel.unprivileged_bpf_disabled = 1 # Enable JIT compiler against SPECTRE variants net.core.bpf_jit_enable = 1 # Harden BPF JIT compiler net.core.bpf_jit_harden = 1 # Prevent SYN attack, enable SYNcookies (they will kick-in when the max_syn_backlog reached) net.ipv4.tcp_syncookies = 1 net.ipv4.tcp_syn_retries = 2 net.ipv4.tcp_synack_retries = 2 net.ipv4.tcp_max_syn_backlog = 4096 # Disable packet forwarding net.ipv4.ip_forward = 0 net.ipv4.conf.all.forwarding = 0 net.ipv4.conf.default.forwarding = 0 net.ipv6.conf.all.forwarding = 0 net.ipv6.conf.default.forwarding = 0 # Enable IP spoofing protection # Turn on source route verification net.ipv4.conf.all.rp_filter = 1 net.ipv4.conf.default.rp_filter = 1 # Disable Redirect Acceptance net.ipv4.conf.all.accept_redirects = 0 net.ipv4.conf.default.accept_redirects = 0 net.ipv4.conf.all.secure_redirects = 0 net.ipv4.conf.default.secure_redirects = 0 net.ipv6.conf.all.accept_redirects = 0 net.ipv6.conf.default.accept_redirects = 0 # Disable Redirect Sending net.ipv4.conf.all.send_redirects = 0 net.ipv4.conf.default.send_redirects = 0 # Disable IP source routing net.ipv4.conf.all.accept_source_route = 0 net.ipv4.conf.default.accept_source_route = 0 net.ipv6.conf.all.accept_source_route = 0 net.ipv6.conf.default.accept_source_route = 0 # Don't relay bootp net.ipv4.conf.all.bootp_relay = 0 # Disable proxy ARP net.ipv4.conf.all.proxy_arp = 0 net.ipv4.conf.all.arp_ignore = 1 net.ipv4.conf.all.arp_announce = 2 # Mitigate time-wait assassination hazards in TCP net.ipv4.tcp_rfc1337 = 1 # Disable logging martian packages # Otherwise it might cause DOS net.ipv4.conf.default.log_martians = 0 net.ipv4.conf.all.log_martians = 0 # Enable bad error message Protection net.ipv4.icmp_ignore_bogus_error_responses = 1 # Enable ignoring broadcasts request net.ipv4.icmp_echo_ignore_broadcasts = 1 # IPv6 DISABLE net.ipv6.conf.all.disable_ipv6 = 1 net.ipv6.conf.default.disable_ipv6 = 1 net.ipv6.conf.lo.disable_ipv6 = 1 # Ensure that subsequent connections use the new values # PUT TO THE END net.ipv4.route.flush = 1 net.ipv6.route.flush = 1
You will need to run
sysctl -p.
to effect the changes on the running system.
Prevent IP spoofing
There is an old configuration option to prevent IP spoofing. However, it was never actually implemented. Sadly there are many documents purporting that this is a useful addition to hardening your system. However, it does not work.
What is interesting is this:
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=773443
was reported in 2014. While this:
https://bugzilla.redhat.com/show_bug.cgi?id=1577265
was reported in 2018, mostly because the entries began to produces errors rather than being ignored…