[{"data":1,"prerenderedAt":1201},["ShallowReactive",2],{"blog-post-\u002Fblog\u002Flinux-server-hardening":3},{"id":4,"title":5,"body":6,"date":1182,"description":1183,"extension":1184,"image":1185,"imageAlt":1186,"imageCaption":1187,"imageHeight":1188,"imageWidth":1189,"meta":1190,"navigation":169,"path":1191,"published":169,"readingTime":1192,"seo":1193,"stem":1194,"tags":1195,"updated":1192,"__hash__":1200},"blog\u002Fblog\u002Flinux-server-hardening.md","Linux Server Hardening: A Complete Security Guide",{"type":7,"value":8,"toc":1166},"minimark",[9,13,18,31,34,37,41,44,109,114,233,236,270,273,275,279,282,286,292,346,349,353,356,363,407,414,418,421,449,452,471,474,540,546,588,594,596,600,849,851,855,858,895,901,938,941,944,969,971,975,978,996,999,1033,1035,1039,1045,1112,1115,1128,1130,1133,1135,1139,1157,1162],[10,11,12],"p",{},"Running a Linux server on the public internet means it will be targeted — constantly. Bots scan for open ports and weak credentials within minutes of a server going live. This guide covers the essential hardening steps to significantly reduce your attack surface and keep your Linux server as secure as possible.",[14,15,17],"h2",{"id":16},"prerequisites","Prerequisites",[19,20,21,25,28],"ul",{},[22,23,24],"li",{},"A Linux server (e.g. Ubuntu, Debian, Fedora)",[22,26,27],{},"Root or sudo access",[22,29,30],{},"Basic familiarity with the terminal",[32,33],"hr",{},[35,36],"distro-selector",{},[14,38,40],{"id":39},"keep-the-system-updated","Keep the System Updated",[10,42,43],{},"The single most impactful thing you can do is keep packages up to date. Most breaches exploit known vulnerabilities that already have patches available.",[45,46,47,86],"pkg-switcher",{},[48,49,51],"template",{"v-slot:apt":50},"",[52,53,57],"pre",{"className":54,"code":55,"language":56,"meta":50,"style":50},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","apt update && apt upgrade -y\n","bash",[58,59,60],"code",{"__ignoreMap":50},[61,62,65,69,73,77,80,83],"span",{"class":63,"line":64},"line",1,[61,66,68],{"class":67},"sBMFI","apt",[61,70,72],{"class":71},"sfazB"," update",[61,74,76],{"class":75},"sMK4o"," &&",[61,78,79],{"class":67}," apt",[61,81,82],{"class":71}," upgrade",[61,84,85],{"class":71}," -y\n",[48,87,88],{"v-slot:dnf":50},[52,89,91],{"className":54,"code":90,"language":56,"meta":50,"style":50},"dnf update && dnf upgrade -y\n",[58,92,93],{"__ignoreMap":50},[61,94,95,98,100,102,105,107],{"class":63,"line":64},[61,96,97],{"class":67},"dnf",[61,99,72],{"class":71},[61,101,76],{"class":75},[61,103,104],{"class":67}," dnf",[61,106,82],{"class":71},[61,108,85],{"class":71},[110,111,113],"h3",{"id":112},"enable-automatic-security-updates","Enable Automatic Security Updates",[45,115,116,147],{},[48,117,118],{"v-slot:apt":50},[52,119,121],{"className":54,"code":120,"language":56,"meta":50,"style":50},"apt install unattended-upgrades -y\ndpkg-reconfigure --priority=low unattended-upgrades\n",[58,122,123,135],{"__ignoreMap":50},[61,124,125,127,130,133],{"class":63,"line":64},[61,126,68],{"class":67},[61,128,129],{"class":71}," install",[61,131,132],{"class":71}," unattended-upgrades",[61,134,85],{"class":71},[61,136,138,141,144],{"class":63,"line":137},2,[61,139,140],{"class":67},"dpkg-reconfigure",[61,142,143],{"class":71}," --priority=low",[61,145,146],{"class":71}," unattended-upgrades\n",[48,148,149],{"v-slot:dnf":50},[52,150,152],{"className":54,"code":151,"language":56,"meta":50,"style":50},"dnf install dnf-automatic -y\n\nsudo tee \u002Fetc\u002Fdnf\u002Fautomatic.conf \u003C\u003C 'EOF'\n[commands]\nupgrade_type = default\napply_updates = yes\nEOF\n\nsystemctl enable --now dnf-automatic-install.timer\n",[58,153,154,165,171,189,195,201,207,213,218],{"__ignoreMap":50},[61,155,156,158,160,163],{"class":63,"line":64},[61,157,97],{"class":67},[61,159,129],{"class":71},[61,161,162],{"class":71}," dnf-automatic",[61,164,85],{"class":71},[61,166,167],{"class":63,"line":137},[61,168,170],{"emptyLinePlaceholder":169},true,"\n",[61,172,174,177,180,183,186],{"class":63,"line":173},3,[61,175,176],{"class":67},"sudo",[61,178,179],{"class":71}," tee",[61,181,182],{"class":71}," \u002Fetc\u002Fdnf\u002Fautomatic.conf",[61,184,185],{"class":75}," \u003C\u003C",[61,187,188],{"class":75}," 'EOF'\n",[61,190,192],{"class":63,"line":191},4,[61,193,194],{"class":71},"[commands]\n",[61,196,198],{"class":63,"line":197},5,[61,199,200],{"class":71},"upgrade_type = default\n",[61,202,204],{"class":63,"line":203},6,[61,205,206],{"class":71},"apply_updates = yes\n",[61,208,210],{"class":63,"line":209},7,[61,211,212],{"class":75},"EOF\n",[61,214,216],{"class":63,"line":215},8,[61,217,170],{"emptyLinePlaceholder":169},[61,219,221,224,227,230],{"class":63,"line":220},9,[61,222,223],{"class":67},"systemctl",[61,225,226],{"class":71}," enable",[61,228,229],{"class":71}," --now",[61,231,232],{"class":71}," dnf-automatic-install.timer\n",[10,234,235],{},"This installs security patches automatically without requiring manual intervention.\nI also recommend rebooting your server once a week to apply kernel updates.\nYou can automate this with a cron job:",[52,237,239],{"className":54,"code":238,"language":56,"meta":50,"style":50},"crontab -e\n0 4 * * 1 \u002Fusr\u002Fsbin\u002Freboot\n",[58,240,241,249],{"__ignoreMap":50},[61,242,243,246],{"class":63,"line":64},[61,244,245],{"class":67},"crontab",[61,247,248],{"class":71}," -e\n",[61,250,251,254,258,262,264,267],{"class":63,"line":137},[61,252,253],{"class":67},"0",[61,255,257],{"class":256},"sbssI"," 4",[61,259,261],{"class":260},"sTEyZ"," *",[61,263,261],{"class":260},[61,265,266],{"class":256}," 1",[61,268,269],{"class":71}," \u002Fusr\u002Fsbin\u002Freboot\n",[10,271,272],{},"This reboots the server every Monday at 04:00 AM.",[32,274],{},[14,276,278],{"id":277},"secure-ssh-access","Secure SSH Access",[10,280,281],{},"SSH is the primary entry point for remote management — and the primary target for brute-force attacks.",[110,283,285],{"id":284},"disable-root-login-and-create-a-new-sudo-user","Disable Root Login And Create A New Sudo User",[10,287,288,289,291],{},"Never allow direct root login over SSH. Always use a regular user with ",[58,290,176],{},".\nIf you haven't already, create a dedicated admin user:",[45,293,294,322],{},[48,295,296],{"v-slot:apt":50},[52,297,299],{"className":54,"code":298,"language":56,"meta":50,"style":50},"adduser username\nusermod -aG sudo username\n",[58,300,301,309],{"__ignoreMap":50},[61,302,303,306],{"class":63,"line":64},[61,304,305],{"class":67},"adduser",[61,307,308],{"class":71}," username\n",[61,310,311,314,317,320],{"class":63,"line":137},[61,312,313],{"class":67},"usermod",[61,315,316],{"class":71}," -aG",[61,318,319],{"class":71}," sudo",[61,321,308],{"class":71},[48,323,324],{"v-slot:dnf":50},[52,325,327],{"className":54,"code":326,"language":56,"meta":50,"style":50},"adduser username\nusermod -aG wheel username\n",[58,328,329,335],{"__ignoreMap":50},[61,330,331,333],{"class":63,"line":64},[61,332,305],{"class":67},[61,334,308],{"class":71},[61,336,337,339,341,344],{"class":63,"line":137},[61,338,313],{"class":67},[61,340,316],{"class":71},[61,342,343],{"class":71}," wheel",[61,345,308],{"class":71},[10,347,348],{},"Switch to that user and verify sudo works before you close your root session.",[110,350,352],{"id":351},"change-default-port","Change default port",[10,354,355],{},"Changing the default port from 22 to something else reduces automated scan noise significantly.",[10,357,358,359,362],{},"Edit ",[58,360,361],{},"\u002Fetc\u002Fssh\u002Fsshd_config",":",[52,364,366],{"className":54,"code":365,"language":56,"meta":50,"style":50},"PermitRootLogin no\nPasswordAuthentication no\nPubkeyAuthentication yes\nAuthorizedKeysFile .ssh\u002Fauthorized_keys\nPort 222\n",[58,367,368,376,383,391,399],{"__ignoreMap":50},[61,369,370,373],{"class":63,"line":64},[61,371,372],{"class":67},"PermitRootLogin",[61,374,375],{"class":71}," no\n",[61,377,378,381],{"class":63,"line":137},[61,379,380],{"class":67},"PasswordAuthentication",[61,382,375],{"class":71},[61,384,385,388],{"class":63,"line":173},[61,386,387],{"class":67},"PubkeyAuthentication",[61,389,390],{"class":71}," yes\n",[61,392,393,396],{"class":63,"line":191},[61,394,395],{"class":67},"AuthorizedKeysFile",[61,397,398],{"class":71}," .ssh\u002Fauthorized_keys\n",[61,400,401,404],{"class":63,"line":197},[61,402,403],{"class":67},"Port",[61,405,406],{"class":256}," 222\n",[10,408,409,410,413],{},"Setting ",[58,411,412],{},"PasswordAuthentication no"," prevents all users from logging in with a password — only key-based authentication is accepted, which is significantly more secure.",[110,415,417],{"id":416},"use-ssh-keys-instead-of-passwords","Use SSH Keys Instead of Passwords",[10,419,420],{},"Generate a key pair on your local machine:",[52,422,424],{"className":54,"code":423,"language":56,"meta":50,"style":50},"ssh-keygen -t ed25519 -C \"your-email@example.com\"\n",[58,425,426],{"__ignoreMap":50},[61,427,428,431,434,437,440,443,446],{"class":63,"line":64},[61,429,430],{"class":67},"ssh-keygen",[61,432,433],{"class":71}," -t",[61,435,436],{"class":71}," ed25519",[61,438,439],{"class":71}," -C",[61,441,442],{"class":75}," \"",[61,444,445],{"class":71},"your-email@example.com",[61,447,448],{"class":75},"\"\n",[10,450,451],{},"Copy the public key to the server:",[52,453,455],{"className":54,"code":454,"language":56,"meta":50,"style":50},"ssh-copy-id -i ~\u002F.ssh\u002Fkey-name.pub username@your-server-ip\n",[58,456,457],{"__ignoreMap":50},[61,458,459,462,465,468],{"class":63,"line":64},[61,460,461],{"class":67},"ssh-copy-id",[61,463,464],{"class":71}," -i",[61,466,467],{"class":71}," ~\u002F.ssh\u002Fkey-name.pub",[61,469,470],{"class":71}," username@your-server-ip\n",[10,472,473],{},"Restart SSH after any config change:",[45,475,476,493],{},[48,477,478],{"v-slot:apt":50},[52,479,481],{"className":54,"code":480,"language":56,"meta":50,"style":50},"systemctl restart sshd\n",[58,482,483],{"__ignoreMap":50},[61,484,485,487,490],{"class":63,"line":64},[61,486,223],{"class":67},[61,488,489],{"class":71}," restart",[61,491,492],{"class":71}," sshd\n",[48,494,495],{"v-slot:dnf":50},[52,496,498],{"className":54,"code":497,"language":56,"meta":50,"style":50},"# SELinux must be told to allow SSH on the new port\nsudo semanage port -a -t ssh_port_t -p tcp 222\nsystemctl restart sshd\n",[58,499,500,506,532],{"__ignoreMap":50},[61,501,502],{"class":63,"line":64},[61,503,505],{"class":504},"sHwdD","# SELinux must be told to allow SSH on the new port\n",[61,507,508,510,513,516,519,521,524,527,530],{"class":63,"line":137},[61,509,176],{"class":67},[61,511,512],{"class":71}," semanage",[61,514,515],{"class":71}," port",[61,517,518],{"class":71}," -a",[61,520,433],{"class":71},[61,522,523],{"class":71}," ssh_port_t",[61,525,526],{"class":71}," -p",[61,528,529],{"class":71}," tcp",[61,531,406],{"class":256},[61,533,534,536,538],{"class":63,"line":173},[61,535,223],{"class":67},[61,537,489],{"class":71},[61,539,492],{"class":71},[10,541,358,542,545],{},[58,543,544],{},"~\u002F.ssh\u002Fconfig"," on your local machine to set up a quick alias for connecting to your server:",[52,547,549],{"className":54,"code":548,"language":56,"meta":50,"style":50},"Host ServerName\nHostname ServerIPAddress\nPort 222\nUser username\nIdentityFile ~\u002F.ssh\u002Fserver-private-key\n",[58,550,551,559,567,573,580],{"__ignoreMap":50},[61,552,553,556],{"class":63,"line":64},[61,554,555],{"class":67},"Host",[61,557,558],{"class":71}," ServerName\n",[61,560,561,564],{"class":63,"line":137},[61,562,563],{"class":67},"Hostname",[61,565,566],{"class":71}," ServerIPAddress\n",[61,568,569,571],{"class":63,"line":173},[61,570,403],{"class":67},[61,572,406],{"class":256},[61,574,575,578],{"class":63,"line":191},[61,576,577],{"class":67},"User",[61,579,308],{"class":71},[61,581,582,585],{"class":63,"line":197},[61,583,584],{"class":67},"IdentityFile",[61,586,587],{"class":71}," ~\u002F.ssh\u002Fserver-private-key\n",[10,589,590,591],{},"Now you can connect to your server like this: ",[58,592,593],{},"ssh ServerName",[32,595],{},[14,597,599],{"id":598},"configure-a-firewall","Configure a Firewall",[45,601,602,740],{},[48,603,604],{"v-slot:apt":50},[52,605,607],{"className":54,"code":606,"language":56,"meta":50,"style":50},"apt install ufw -y\n\n# Deny all incoming by default\nufw default deny incoming\nufw default allow outgoing\n\n# Allow SSH on the custom port\nufw allow 222\u002Ftcp\n\n# Allow web traffic if needed\nufw allow 80\u002Ftcp\nufw allow 443\u002Ftcp\nufw allow 443\u002Fudp # important for http protocol version 3\n\nufw enable\nufw status verbose\n",[58,608,609,620,624,629,643,655,659,664,673,677,683,693,703,716,721,729],{"__ignoreMap":50},[61,610,611,613,615,618],{"class":63,"line":64},[61,612,68],{"class":67},[61,614,129],{"class":71},[61,616,617],{"class":71}," ufw",[61,619,85],{"class":71},[61,621,622],{"class":63,"line":137},[61,623,170],{"emptyLinePlaceholder":169},[61,625,626],{"class":63,"line":173},[61,627,628],{"class":504},"# Deny all incoming by default\n",[61,630,631,634,637,640],{"class":63,"line":191},[61,632,633],{"class":67},"ufw",[61,635,636],{"class":71}," default",[61,638,639],{"class":71}," deny",[61,641,642],{"class":71}," incoming\n",[61,644,645,647,649,652],{"class":63,"line":197},[61,646,633],{"class":67},[61,648,636],{"class":71},[61,650,651],{"class":71}," allow",[61,653,654],{"class":71}," outgoing\n",[61,656,657],{"class":63,"line":203},[61,658,170],{"emptyLinePlaceholder":169},[61,660,661],{"class":63,"line":209},[61,662,663],{"class":504},"# Allow SSH on the custom port\n",[61,665,666,668,670],{"class":63,"line":215},[61,667,633],{"class":67},[61,669,651],{"class":71},[61,671,672],{"class":71}," 222\u002Ftcp\n",[61,674,675],{"class":63,"line":220},[61,676,170],{"emptyLinePlaceholder":169},[61,678,680],{"class":63,"line":679},10,[61,681,682],{"class":504},"# Allow web traffic if needed\n",[61,684,686,688,690],{"class":63,"line":685},11,[61,687,633],{"class":67},[61,689,651],{"class":71},[61,691,692],{"class":71}," 80\u002Ftcp\n",[61,694,696,698,700],{"class":63,"line":695},12,[61,697,633],{"class":67},[61,699,651],{"class":71},[61,701,702],{"class":71}," 443\u002Ftcp\n",[61,704,706,708,710,713],{"class":63,"line":705},13,[61,707,633],{"class":67},[61,709,651],{"class":71},[61,711,712],{"class":71}," 443\u002Fudp",[61,714,715],{"class":504}," # important for http protocol version 3\n",[61,717,719],{"class":63,"line":718},14,[61,720,170],{"emptyLinePlaceholder":169},[61,722,724,726],{"class":63,"line":723},15,[61,725,633],{"class":67},[61,727,728],{"class":71}," enable\n",[61,730,732,734,737],{"class":63,"line":731},16,[61,733,633],{"class":67},[61,735,736],{"class":71}," status",[61,738,739],{"class":71}," verbose\n",[48,741,742],{"v-slot:dnf":50},[52,743,745],{"className":54,"code":744,"language":56,"meta":50,"style":50},"# firewalld is installed by default on Fedora\u002FRHEL\nsystemctl enable --now firewalld\n\n# Allow SSH on the custom port\nfirewall-cmd --permanent --add-port=222\u002Ftcp\nfirewall-cmd --permanent --remove-service=ssh\n\n# Allow web traffic if needed\nfirewall-cmd --permanent --add-service=http\nfirewall-cmd --permanent --add-service=https\nsudo firewall-cmd --permanent --add-port=443\u002Fudp # important for http protocol version 3\n\nfirewall-cmd --reload\nfirewall-cmd --list-all\n",[58,746,747,752,763,767,771,782,791,795,799,808,817,831,835,842],{"__ignoreMap":50},[61,748,749],{"class":63,"line":64},[61,750,751],{"class":504},"# firewalld is installed by default on Fedora\u002FRHEL\n",[61,753,754,756,758,760],{"class":63,"line":137},[61,755,223],{"class":67},[61,757,226],{"class":71},[61,759,229],{"class":71},[61,761,762],{"class":71}," firewalld\n",[61,764,765],{"class":63,"line":173},[61,766,170],{"emptyLinePlaceholder":169},[61,768,769],{"class":63,"line":191},[61,770,663],{"class":504},[61,772,773,776,779],{"class":63,"line":197},[61,774,775],{"class":67},"firewall-cmd",[61,777,778],{"class":71}," --permanent",[61,780,781],{"class":71}," --add-port=222\u002Ftcp\n",[61,783,784,786,788],{"class":63,"line":203},[61,785,775],{"class":67},[61,787,778],{"class":71},[61,789,790],{"class":71}," --remove-service=ssh\n",[61,792,793],{"class":63,"line":209},[61,794,170],{"emptyLinePlaceholder":169},[61,796,797],{"class":63,"line":215},[61,798,682],{"class":504},[61,800,801,803,805],{"class":63,"line":220},[61,802,775],{"class":67},[61,804,778],{"class":71},[61,806,807],{"class":71}," --add-service=http\n",[61,809,810,812,814],{"class":63,"line":679},[61,811,775],{"class":67},[61,813,778],{"class":71},[61,815,816],{"class":71}," --add-service=https\n",[61,818,819,821,824,826,829],{"class":63,"line":685},[61,820,176],{"class":67},[61,822,823],{"class":71}," firewall-cmd",[61,825,778],{"class":71},[61,827,828],{"class":71}," --add-port=443\u002Fudp",[61,830,715],{"class":504},[61,832,833],{"class":63,"line":695},[61,834,170],{"emptyLinePlaceholder":169},[61,836,837,839],{"class":63,"line":705},[61,838,775],{"class":67},[61,840,841],{"class":71}," --reload\n",[61,843,844,846],{"class":63,"line":718},[61,845,775],{"class":67},[61,847,848],{"class":71}," --list-all\n",[32,850],{},[14,852,854],{"id":853},"install-fail2ban","Install fail2ban",[10,856,857],{},"fail2ban monitors log files and automatically bans IPs that show signs of brute-force attacks.",[45,859,860,878],{},[48,861,862],{"v-slot:apt":50},[52,863,865],{"className":54,"code":864,"language":56,"meta":50,"style":50},"apt install fail2ban -y\n",[58,866,867],{"__ignoreMap":50},[61,868,869,871,873,876],{"class":63,"line":64},[61,870,68],{"class":67},[61,872,129],{"class":71},[61,874,875],{"class":71}," fail2ban",[61,877,85],{"class":71},[48,879,880],{"v-slot:dnf":50},[52,881,883],{"className":54,"code":882,"language":56,"meta":50,"style":50},"dnf install fail2ban -y\n",[58,884,885],{"__ignoreMap":50},[61,886,887,889,891,893],{"class":63,"line":64},[61,888,97],{"class":67},[61,890,129],{"class":71},[61,892,875],{"class":71},[61,894,85],{"class":71},[10,896,358,897,900],{},[58,898,899],{},"\u002Fetc\u002Ffail2ban\u002Fjail.local"," and create the following config:",[52,902,906],{"className":903,"code":904,"language":905,"meta":50,"style":50},"language-ini shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","[sshd]\nenabled  = true\nport     = 222\nmaxretry = 2\nbantime  = 30d\nfindtime = 24h\n","ini",[58,907,908,913,918,923,928,933],{"__ignoreMap":50},[61,909,910],{"class":63,"line":64},[61,911,912],{},"[sshd]\n",[61,914,915],{"class":63,"line":137},[61,916,917],{},"enabled  = true\n",[61,919,920],{"class":63,"line":173},[61,921,922],{},"port     = 222\n",[61,924,925],{"class":63,"line":191},[61,926,927],{},"maxretry = 2\n",[61,929,930],{"class":63,"line":197},[61,931,932],{},"bantime  = 30d\n",[61,934,935],{"class":63,"line":203},[61,936,937],{},"findtime = 24h\n",[10,939,940],{},"These settings ban any IP after 2 failed login attempts within 24 hours, for 30 days.\nThis is an aggressive configuration, but with public key authentication you should never need more than one attempt anyway.",[10,942,943],{},"Start and enable fail2ban:",[52,945,947],{"className":54,"code":946,"language":56,"meta":50,"style":50},"systemctl enable --now fail2ban\nfail2ban-client status sshd\n",[58,948,949,960],{"__ignoreMap":50},[61,950,951,953,955,957],{"class":63,"line":64},[61,952,223],{"class":67},[61,954,226],{"class":71},[61,956,229],{"class":71},[61,958,959],{"class":71}," fail2ban\n",[61,961,962,965,967],{"class":63,"line":137},[61,963,964],{"class":67},"fail2ban-client",[61,966,736],{"class":71},[61,968,492],{"class":71},[32,970],{},[14,972,974],{"id":973},"disable-unused-services","Disable Unused Services",[10,976,977],{},"Every running service is a potential attack surface. List what's running:",[52,979,981],{"className":54,"code":980,"language":56,"meta":50,"style":50},"systemctl list-units --type=service --state=running\n",[58,982,983],{"__ignoreMap":50},[61,984,985,987,990,993],{"class":63,"line":64},[61,986,223],{"class":67},[61,988,989],{"class":71}," list-units",[61,991,992],{"class":71}," --type=service",[61,994,995],{"class":71}," --state=running\n",[10,997,998],{},"Disable anything you don't need, for example:",[52,1000,1002],{"className":54,"code":1001,"language":56,"meta":50,"style":50},"systemctl disable --now avahi-daemon # allowing devices on a local network to automatically discover each other \nsystemctl disable --now cups # printer service\n",[58,1003,1004,1019],{"__ignoreMap":50},[61,1005,1006,1008,1011,1013,1016],{"class":63,"line":64},[61,1007,223],{"class":67},[61,1009,1010],{"class":71}," disable",[61,1012,229],{"class":71},[61,1014,1015],{"class":71}," avahi-daemon",[61,1017,1018],{"class":504}," # allowing devices on a local network to automatically discover each other \n",[61,1020,1021,1023,1025,1027,1030],{"class":63,"line":137},[61,1022,223],{"class":67},[61,1024,1010],{"class":71},[61,1026,229],{"class":71},[61,1028,1029],{"class":71}," cups",[61,1031,1032],{"class":504}," # printer service\n",[32,1034],{},[14,1036,1038],{"id":1037},"harden-kernel-parameters-with-sysctl","Harden Kernel Parameters with sysctl",[10,1040,1041,1042,362],{},"Add the following to ",[58,1043,1044],{},"\u002Fetc\u002Fsysctl.d\u002F99-hardening.conf",[52,1046,1048],{"className":903,"code":1047,"language":905,"meta":50,"style":50},"# Prevent IP spoofing\nnet.ipv4.conf.all.rp_filter = 1\nnet.ipv4.conf.default.rp_filter = 1\n\n# Ignore ICMP redirects\nnet.ipv4.conf.all.accept_redirects = 0\nnet.ipv6.conf.all.accept_redirects = 0\n\n# Ignore broadcast pings\nnet.ipv4.icmp_echo_ignore_broadcasts = 1\n\n# Disable SYN flood attacks\nnet.ipv4.tcp_syncookies = 1\n",[58,1049,1050,1055,1060,1065,1069,1074,1079,1084,1088,1093,1098,1102,1107],{"__ignoreMap":50},[61,1051,1052],{"class":63,"line":64},[61,1053,1054],{},"# Prevent IP spoofing\n",[61,1056,1057],{"class":63,"line":137},[61,1058,1059],{},"net.ipv4.conf.all.rp_filter = 1\n",[61,1061,1062],{"class":63,"line":173},[61,1063,1064],{},"net.ipv4.conf.default.rp_filter = 1\n",[61,1066,1067],{"class":63,"line":191},[61,1068,170],{"emptyLinePlaceholder":169},[61,1070,1071],{"class":63,"line":197},[61,1072,1073],{},"# Ignore ICMP redirects\n",[61,1075,1076],{"class":63,"line":203},[61,1077,1078],{},"net.ipv4.conf.all.accept_redirects = 0\n",[61,1080,1081],{"class":63,"line":209},[61,1082,1083],{},"net.ipv6.conf.all.accept_redirects = 0\n",[61,1085,1086],{"class":63,"line":215},[61,1087,170],{"emptyLinePlaceholder":169},[61,1089,1090],{"class":63,"line":220},[61,1091,1092],{},"# Ignore broadcast pings\n",[61,1094,1095],{"class":63,"line":679},[61,1096,1097],{},"net.ipv4.icmp_echo_ignore_broadcasts = 1\n",[61,1099,1100],{"class":63,"line":685},[61,1101,170],{"emptyLinePlaceholder":169},[61,1103,1104],{"class":63,"line":695},[61,1105,1106],{},"# Disable SYN flood attacks\n",[61,1108,1109],{"class":63,"line":705},[61,1110,1111],{},"net.ipv4.tcp_syncookies = 1\n",[10,1113,1114],{},"Apply the changes:",[52,1116,1118],{"className":54,"code":1117,"language":56,"meta":50,"style":50},"sysctl --system\n",[58,1119,1120],{"__ignoreMap":50},[61,1121,1122,1125],{"class":63,"line":64},[61,1123,1124],{"class":67},"sysctl",[61,1126,1127],{"class":71}," --system\n",[32,1129],{},[10,1131,1132],{},"Security is not a one-time task. Revisit your server configuration regularly, monitor your logs, and stay informed about newly discovered vulnerabilities in the software you run.",[32,1134],{},[14,1136,1138],{"id":1137},"bonus-monitoring-and-alerting","Bonus – Monitoring and Alerting",[10,1140,1141,1142,1149,1150],{},"One bonus tip: install a monitoring tool like ",[1143,1144,1148],"a",{"href":1145,"rel":1146},"https:\u002F\u002Fgithub.com\u002Fhenrygd\u002Fbeszel",[1147],"nofollow","Beszel",".\nIt's clean, well-designed, and I was immediately impressed by how easy it is to set up.\nYou can monitor your server's performance and configure alerts for when something looks off.\nI've set up alerts via ntfy, so I get a push notification directly on my iPhone whenever something like high CPU usage persists for an extended period or similar issues occur.\nBeszel also lets you monitor the status and performance of your Docker containers.\nIt runs on all major platforms — Windows, Linux, and macOS. If you want to step up your monitoring game, give it a shot.\nI'd wholeheartedly recommend it to any fellow IT professional. Here's a screenshot of the UI:\n",[1151,1152],"img",{"alt":1153,"height":1154,"src":1155,"width":1156},"Linux Server Hardening – A terminal showing active firewall and fail2ban protection",2551,"\u002Fimages\u002Fblog\u002Flinux-server-hardening\u002Fbeszel.webp",1422,[1158,1159],"comment-section",{"section":1160,"slug":1161},"blog","linux-server-hardening",[1163,1164,1165],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"title":50,"searchDepth":137,"depth":137,"links":1167},[1168,1169,1172,1177,1178,1179,1180,1181],{"id":16,"depth":137,"text":17},{"id":39,"depth":137,"text":40,"children":1170},[1171],{"id":112,"depth":173,"text":113},{"id":277,"depth":137,"text":278,"children":1173},[1174,1175,1176],{"id":284,"depth":173,"text":285},{"id":351,"depth":173,"text":352},{"id":416,"depth":173,"text":417},{"id":598,"depth":137,"text":599},{"id":853,"depth":137,"text":854},{"id":973,"depth":137,"text":974},{"id":1037,"depth":137,"text":1038},{"id":1137,"depth":137,"text":1138},"2026-05-16","A step-by-step guide to securing your Linux server — SSH hardening, firewall setup, fail2ban, automatic security updates, and more. Harden your server in under an hour.","md","\u002Fimages\u002Fblog\u002Flinux-server-hardening\u002Fheader.webp","A terminal showing active firewall and fail2ban protection on a Linux server","A hardened Linux server — firewall active, fail2ban watching, root login disabled.",1024,1536,{},"\u002Fblog\u002Flinux-server-hardening",null,{"title":5,"description":1183},"blog\u002Flinux-server-hardening",[1196,1197,1198,1199],"linux","security","server","devops","XjdP8s_N-VGGnTkwWa63x7lJskx0K3uayLylPQBU93Q",1782795478211]