CIS Controls in Config Files: Core Dumps, cron, Modules, sysctl and TLS
- Explain how a CIS control is audited: a persistent setting in a file, plus an effective value you read back
- Restrict core dumps three ways: a pam_limits hard limit, fs.suid_dumpable = 0 in /etc/sysctl.d, and systemd-coredump Storage=none, and verify the limit in a new login shell
- Allow-list cron and at with cron.allow / at.allow, know which file wins, and set safe ownership and modes on /etc/crontab and the /etc/cron.* directories
- Stop unused filesystem modules from loading with install <module> /bin/false and blacklist in /etc/modprobe.d, and verify with modprobe -n -v
- Persist the CIS network sysctls (redirects, source routing, martians, broadcast echo, rp_filter) in /etc/sysctl.d, predict which file wins, and know when sysctl --system or sysctl -p applies them
- Set a system-wide OpenSSL floor (MinProtocol, CipherString @SECLEVEL) in openssl.cnf, prove OpenSSL reads it, and recognise RHEL's update-crypto-policies equivalent
How a CIS control is checked
Separate the persistent setting a scanner reads from the effective value the system uses right now.
The CIS Benchmarks are consensus hardening checklists: a few hundred numbered controls per distribution, each with an audit (how to prove it) and a remediation (how to fix it). A scanner such as CIS-CAT or OpenSCAP walks that list on your host and marks each control pass or fail.
For the controls in this lesson the audit reads configuration files, because the file is what survives a reboot. A value you set live with
sysctl -wand never wrote down is gone at the next boot, and the next scan fails it again. So every control here has the same two halves the hardening guide taught: the persistent setting (one line in the right file) and the effective value (what the running system does now). Write the first, then prove the second with the tool that reads it back.The five families below come from the CIS Ubuntu 22.04 benchmark and its STIG neighbours: core dumps, cron access, unused kernel modules, network kernel parameters and the system-wide TLS policy. Each step shows where the setting lives, the exact line, and how to check it.
Check yourself
A colleague runs sysctl -w net.ipv4.conf.all.accept_redirects=0, sees sysctl -n print 0, and closes the CIS finding. The next week's scan fails it again after a reboot. What was missing?
Core dumps: a hard limit, a sysctl and systemd-coredump
Forbid core dumps for ordinary logins and setuid programs, and verify the limit where it applies.
A core dump is a copy of a crashed process's memory written to disk. That memory can hold whatever the process was handling: private keys, session tokens, password hashes read from
/etc/shadow. CIS closes it in three places, because three different mechanisms produce dumps:- *` hard core 0
** in/etc/security/limits.conf(or a.conf` file in `/etc/security/limits.d/`, which `pam_limits` also reads). A hard* limit is a ceiling the user can't raise, soulimit -c unlimitedfails. Some scanners only readlimits.confitself, so when the benchmark names that file, put the line there. - `fs.suid_dumpable = 0` in a file under
/etc/sysctl.d/. It decides whether a process that changed privilege (a setuid program such aspasswd) may dump at all:0never,1always (debugging only),2only as a root-readable file. - `Storage=none` in the
[Coredump]section of/etc/systemd/coredump.conf, for hosts wheresystemd-coredumpcatches crashes and stores them under/var/lib/systemd/coredump.ProcessSizeMax=0stops it from even processing one.
echo '* hard core 0' >> /etc/security/limits.conf su - student -c 'ulimit -c; ulimit -Hc' su - student -c 'ulimit -c unlimited'0 0 -bash: line 1: ulimit: core file size: cannot modify limit: Operation not permitted
- su - student -c
- Start a login session as student (PAM session modules run, so limits apply) and run one command.
- ulimit -c / -Hc
- Print the soft / hard limit on core file size, in 1024-byte blocks.
pam_limitsapplies limits when a session opens, so your current shell never sees the new line. Verify in a new login shell instead:su - studentruns the PAM session stack exactly like a real login. Both the soft (ulimit -c) and hard (ulimit -Hc) core limits are now 0, and the attempt to raise the limit is refused. Note the wildcard*does not cover root:pam_limitsskips wildcard and group lines for uid 0, so add an explicitroot hard core 0line if your policy wants root covered too.echo 'fs.suid_dumpable = 0' > /etc/sysctl.d/60-cis-coredump.conf printf '[Coredump]\nStorage=none\nProcessSizeMax=0\n' > /etc/systemd/coredump.conf grep -H suid_dumpable /etc/sysctl.d/*.conf systemd-analyze cat-config systemd/coredump.conf/etc/sysctl.d/60-cis-coredump.conf:fs.suid_dumpable = 0 # /etc/systemd/coredump.conf [Coredump] Storage=none ProcessSizeMax=0
- grep -H
- Prefix every match with its file name, so you see which file sets the key.
- cat-config systemd/coredump.conf
- Show a systemd config file plus its drop-ins, in the order they apply.
The other two halves, written and read back. The grepover every drop-in proves exactly one file sets the key, so nothing later overrides it.systemd-analyze cat-configprintscoredump.confmerged with any drop-ins in/etc/systemd/coredump.conf.d/, in the order systemd-coredump would read them, so it also catches an override a plaincatof one file would miss.Example — not runnable on your lab box
sysctl -p /etc/sysctl.d/60-cis-coredump.conf sysctl -n fs.suid_dumpablefs.suid_dumpable = 0 0
- -p FILE
- Load settings from FILE and print each key it set (default file: /etc/sysctl.conf).
- -n
- Print only the value, not the key name.
On a real host, apply the file now and read the live kernel value back. sysctl -p FILEloads one file and echoes each key it set;sysctl -nprints just the value. On the lab container this write is refused, which is why the file itself is what gets graded there.- *` hard core 0
cron and at: allow-list who may schedule
Use cron.allow and at.allow correctly and lock down the cron configuration files.
Scheduled jobs are a favourite persistence spot, so CIS limits who may create them and protects the files that define them. Access is decided by two pairs of files, read the same way by
crontaband byat:- If `/etc/cron.allow` exists, only the users listed in it may use
crontab.cron.denyis then ignored entirely, so a user listed in both is allowed: the allow file wins. - If only `/etc/cron.deny` exists, everyone may use
crontabexcept the users it lists. That is a blocklist, and every account created later is allowed by default. - If neither exists, it's a build-time default: Debian and Ubuntu allow everyone, some builds allow only root. (RHEL ships an empty
cron.deny, which also allows everyone.)
at.allowandat.denywork the same way forat, except that with neither file only root may use it. Root can always use both tools. CIS wants the allow-list model:cron.allowandat.allowpresent, listing only the accounts that need them, and the deny files removed so nobody mistakes them for the control.touch /etc/cron.allow chown root:crontab /etc/cron.allow && chmod 640 /etc/cron.allow su - student -c 'crontab -l' echo student >> /etc/cron.allow su - student -c 'crontab -l'You (student) are not allowed to use this program (crontab) See crontab(1) for more information no crontab for student
- crontab -l
- List the calling user's crontab. A refusal here is the access check, before any crontab is read.
An empty cron.allowlocks every non-root user out at once. Addingstudentlets that one account back in:no crontab for studentiscrontabworking normally and finding nothing to list. On Debian and Ubuntu the file isroot:crontabmode 640 becausecrontabruns setgid crontab and must read it.chmod 600 /etc/crontab chmod 700 /etc/cron.d /etc/cron.hourly /etc/cron.daily /etc/cron.weekly /etc/cron.monthly rm -f /etc/cron.deny echo root > /etc/at.allow && chown root:daemon /etc/at.allow && chmod 640 /etc/at.allow stat -c '%a %U:%G %n' /etc/crontab /etc/cron.d /etc/cron.allow /etc/at.allow su - student -c 'atq'600 root:root /etc/crontab 700 root:root /etc/cron.d 640 root:crontab /etc/cron.allow 640 root:daemon /etc/at.allow You do not have permission to use atq.
- stat -c '%a %U:%G %n'
- Print octal permissions, owner:group and path for each file.
- atq
- List pending at jobs; refused when at.allow exists and doesn't list you.
The file side of the control. /etc/crontaband the/etc/cron.*directories hold root's jobs, so only root should read or change them: an attacker who can read them learns what runs as root and when, and one who can write them runs code as root.stat -c '%a %U:%G %n'prints the octal mode, owner, group and name: exactly what an audit compares.at.allowlists only root (ownedroot:daemon, the groupatruns as on Ubuntu), sostudentis refused.Check yourself
/etc/cron.allow lists alice and /etc/cron.deny lists alice too. Can alice use crontab?
- If `/etc/cron.allow` exists, only the users listed in it may use
Kernel modules: make unused filesystems impossible to load
Disable a module with install <module> /bin/false plus blacklist, and verify what modprobe would do.
Linux loads most drivers on demand. Mount a
cramfsorudfimage, or plug in a USB stick, and the kernel asksmodprobeto load the matching module, pulling rarely-used and rarely-audited filesystem code into the kernel because of a file an attacker handed you. CIS lists the filesystems most servers never use (cramfs,freevxfs,hfs,hfsplus,jffs2,udf, andusb-storagefor removable media) and wants each one unloadable.Two lines in a file under
/etc/modprobe.d/do it, and they do different jobs. The file name must end in.conf:modprobereads only*.conffiles there, so the same lines incis.conf.bakorcis.txtdo nothing, andmodprobe -n -v cramfswill tell you so.- `install <module> /bin/false` tells
modprobeto run/bin/falseinstead of loading the module. Every load request fails, including an explicitmodprobe <module>by root. - `blacklist <module>` only stops the module from loading automatically through an alias (the udev and hardware path). An explicit
modprobestill loads a module that is only blacklisted.
CIS wants both: the
installline is the actual stop, and theblacklistline is what its audit also looks for.printf '%s\n' 'install cramfs /bin/false' 'blacklist cramfs' 'install udf /bin/false' 'blacklist udf' > /etc/modprobe.d/cis-filesystems.conf modprobe -n -v cramfs modprobe --showconfig | grep -E '^(install|blacklist) (cramfs|udf)'install /bin/false blacklist cramfs blacklist udf install cramfs /bin/false install udf /bin/false
- -n
- Dry run: do everything except load or run anything.
- -v
- Verbose: print each insmod or install command modprobe would execute.
- --showconfig
- Print the effective configuration merged from all modprobe.d files.
modprobe -n -vis a dry run: it resolves the request through every config file and prints what it would do, without touching the kernel.install /bin/falseis the pass: loading cramfs now means running/bin/false. A module still enabled would print aninsmod /lib/modules/.../cramfs.koline instead (or, on this container, which ships no modules,Module cramfs not found).--showconfigdumps the merged configuration from every file in/etc/modprobe.d, so thegrepproves your lines are what modprobe actually sees.modprobe cramfs 2>&1; echo "exit status: $?"modprobe: ERROR: ../libkmod/libkmod-module.c:990 command_do() Error running install command '/bin/false' for module cramfs: retcode 1 modprobe: ERROR: could not insert 'cramfs': Invalid argument exit status: 1
A real load attempt, which is safe here because the installline replaces the load with/bin/false. modprobe ran the install command, saw it fail, and refused. That is the behaviour every request for cramfs now gets, whether it comes from root, a mount or udev.- `install <module> /bin/false` tells
Network sysctls: redirects, source routes and spoofed sources
Persist the CIS network kernel parameters and predict which file's value wins.
CIS section 3.3 tunes how the kernel treats packets that try to change its routing. Most keys come in
allanddefaultpairs.net.ipv4.conf.all.<key>covers every interface that exists now (for most of these keys the kernel combines it with the per-interface value), andnet.ipv4.conf.default.<key>is the template copied to interfaces created later. Set both.| Key | CIS value | Why |
|---|---|---|
|
accept_redirects| 0 | An ICMP redirect rewrites your route table. A forged one sends your traffic through the attacker. ||
secure_redirects| 0 | The same, for redirects claiming to come from a listed gateway. ||
send_redirects| 0 | Only routers send redirects. A server that does is misconfigured. ||
accept_source_route| 0 | Source-routed packets choose their own path, which bypasses your network's filtering. ||
log_martians| 1 | Log packets with impossible source addresses, an early sign of spoofing. ||
rp_filter| 1 | Strict reverse-path filtering: drop a packet whose source isn't reachable back through the interface it arrived on.2is the looser mode. ||
icmp_echo_ignore_broadcasts| 1 | Ignore pings sent to a broadcast address (smurf amplification). It has noall/defaultpair. |Write them to one drop-in. The file name matters, as the next block shows.
cat > /etc/sysctl.d/60-cis-net.conf <<'EOF' net.ipv4.conf.all.accept_redirects = 0 net.ipv4.conf.default.accept_redirects = 0 net.ipv4.conf.all.send_redirects = 0 net.ipv4.conf.default.send_redirects = 0 net.ipv4.conf.all.rp_filter = 1 net.ipv4.conf.default.rp_filter = 1 EOF systemd-analyze cat-config sysctl.d | grep -E '^net\.ipv4\.conf\.(all|\*)\.rp_filter'net.ipv4.conf.all.rp_filter=2 net.ipv4.conf.*.rp_filter = 2 net.ipv4.conf.all.rp_filter = 1
- cat-config sysctl.d
- Concatenate every sysctl.d file in the order they are applied, each headed by its path.
Every *.conffile in/etc/sysctl.d,/run/sysctl.dand/usr/lib/sysctl.dis applied in file-name order (a file in/etcreplaces one with the same name in/usr/lib), and the last assignment of a key wins.cat-configprints them in that order, so read the result bottom-up. Ubuntu shipsrp_filter=2twice, in10-network-security.confand systemd's50-default.conf. Your60-file sorts after both, so its1is the value the box boots with. Name the same file10-cis.confand it is silently overridden, and the scan fails although the line is right there.Example — not runnable on your lab box
sysctl -p /etc/sysctl.d/60-cis-net.conf sysctl -n net.ipv4.conf.all.accept_redirects net.ipv4.conf.all.rp_filternet.ipv4.conf.all.accept_redirects = 0 net.ipv4.conf.default.accept_redirects = 0 net.ipv4.conf.all.send_redirects = 0 net.ipv4.conf.default.send_redirects = 0 net.ipv4.conf.all.rp_filter = 1 net.ipv4.conf.default.rp_filter = 1 0 1
- -p FILE
- Load settings from FILE and print each key it set (default file: /etc/sysctl.conf).
- -n
- Print only the value, not the key name.
On a real host, apply and read back. sysctl -p FILEapplies one file and ignores precedence, so it can show your value even when a later file will override it at boot.sysctl --systemre-applies every file in boot order, which makes it the honest check that the boot result is what you want.sysctl -pwith no file reads only/etc/sysctl.conf.sysctl -n KEY...prints the live values.Check yourself
/usr/lib/sysctl.d/50-default.conf sets net.ipv4.conf.all.rp_filter = 2 and you add /etc/sysctl.d/40-cis.conf with rp_filter = 1. What value does the host boot with?
TLS: a system-wide OpenSSL floor
Wire a system_default section into openssl.cnf, set MinProtocol and SECLEVEL, and prove OpenSSL reads it.
Every program linked against OpenSSL (web servers, mail,
curl, scripts) readsopenssl.cnfwhen it starts. A system default section in that file sets a floor all of them inherit unless the program overrides it. Two directives carry the policy:- `MinProtocol = TLSv1.2` refuses TLS 1.0 and 1.1.
- `CipherString = DEFAULT@SECLEVEL=2` sets the security level. Level 2 means at least 112-bit security: RSA and DH keys of 2048 bits or more, no SHA-1 certificate signatures, no export or NULL ciphers. Level 3 raises RSA to 3072 bits.
The section is reached through a chain of names, and every link has to be there:
1.
openssl_conf = <init>in the global section, meaning above the first[header]. Anything below a header belongs to that section, and OpenSSL never looks foropenssl_confthere.2.
[<init>]withssl_conf = <ssl>.3.
[<ssl>]withsystem_default = <policy>.4.
[<policy>]with the directives.The section names are yours to choose. Ubuntu 22.04 already ships the chain with
SECLEVEL=2but noMinProtocol. A trimmed or hand-written file may have no chain at all.openssl version -d cnf="$(openssl version -d | cut -d'"' -f2)/openssl.cnf" grep -nE '^(openssl_conf|ssl_conf|system_default|CipherString|MinProtocol) *=|^\[ *(openssl_init|ssl_sect|system_default_sect) *\]' "$cnf"OPENSSLDIR: "/usr/lib/ssl" 17:openssl_conf = openssl_init 53:[openssl_init] 55:ssl_conf = ssl_sect 393:[ssl_sect] 394:system_default = system_default_sect 396:[system_default_sect] 397:CipherString = DEFAULT:@SECLEVEL=2
- version -d
- Print OPENSSLDIR, where OpenSSL looks for openssl.cnf.
- grep -n
- Show line numbers, so you can see openssl_conf sits above the first [section].
openssl version -dnames the directory OpenSSL readsopenssl.cnffrom, and the second line builds the file's path from it, so you grep the file OpenSSL really uses. On Ubuntu/usr/lib/ssl/openssl.cnfis a symlink to/etc/ssl/openssl.cnf; on RHEL the file is/etc/pki/tls/openssl.cnf. Thegrepwalks the chain on a stock Ubuntu file:openssl_confon line 17, above every header, then each link down to[system_default_sect]. To add the floor here, putMinProtocol = TLSv1.2under that last header. If the grep finds noopenssl_confline, you build all four links yourself, as in the next block.cat > /root/policy.cnf <<'EOF' openssl_conf = default_conf [default_conf] ssl_conf = ssl_sect [ssl_sect] system_default = system_default_sect [system_default_sect] MinProtocol = TLSv1.2 CipherString = DEFAULT@SECLEVEL=2 EOF key=/root/tls-demo.key crt=/root/tls-demo.crt openssl req -x509 -newkey rsa:2048 -nodes -keyout "$key" -out "$crt" -subj "/CN=localhost" -days 1 2>/dev/null sed 's/SECLEVEL=2/SECLEVEL=3/' /root/policy.cnf > /root/probe.cnf OPENSSL_CONF=/root/probe.cnf timeout 3 openssl s_server -accept 127.0.0.1:8443 -cert "$crt" -key "$key" </dev/null 2>&1 | grep -o 'ee key too small'ee key too small
- OPENSSL_CONF=FILE
- Environment variable: read this config file instead of OPENSSLDIR/openssl.cnf.
- req -x509 -newkey rsa:2048 -nodes
- Make a throwaway self-signed certificate and an unencrypted 2048-bit RSA key.
- s_server -cert -key
- Start a test TLS server. It checks the key against the security level before it listens.
A complete chain, and a test that proves OpenSSL reads it. OPENSSL_CONFpoints any OpenSSL program at a file of your choice, so you can try a policy before touching the system one. Ubuntu's built-in default is already level 2, so a level-2 policy behaves the same whether or not it is read. The probe raises the level to 3 instead: a 2048-bit RSA certificate passes level 2 but not level 3, sos_serverrefuses to load it withee key too smallonly if your[system_default_sect]was applied. If the server starts listening instead (ACCEPT), the chain is broken, and the usual cause isopenssl_confsitting below a[header]. Run the same probe withoutOPENSSL_CONFafter editing/etc/ssl/openssl.cnf.Example — not runnable on your lab box
update-crypto-policies --show grep -oE '^TLS\.MinProtocol = .*|@SECLEVEL=[0-9]' /etc/crypto-policies/back-ends/opensslcnf.config update-crypto-policies --set FUTUREDEFAULT @SECLEVEL=2 TLS.MinProtocol = TLSv1.2 Setting system policy to FUTURE Note: System-wide crypto policies are applied on application start-up. It is recommended to restart the system for the change of policies to fully take place.
- --show
- Print the system-wide policy in force.
- --set POLICY
- Regenerate every back-end file for POLICY.
RHEL, Rocky and Fedora don't have you edit openssl.cnfby hand. Theiropenssl.cnfincludes a generated back-end file, andupdate-crypto-policieswrites that file, plus the matching ones for GnuTLS, NSS, Java and OpenSSH, from one named policy:LEGACY,DEFAULT,FUTUREorFIPS, optionally with modifiers such asDEFAULT:NO-SHA1.--showprints the active policy, and the back-end file shows what it means for OpenSSL.FUTUREraises OpenSSL to@SECLEVEL=3. Programs pick up the change when they restart. Output from Rocky 9; the Ubuntu lab box doesn't have this tool.Check yourself
openssl.cnf starts with a [ req ] section, and you append openssl_conf = default_conf plus the three policy sections at the end of the file. Does the policy apply?
Now do it: audit these controls on the sandbox
Run the read-only checks a CIS scan makes and say pass or fail for each.
Run these in your lab terminal as a mini CIS audit. Each one only reads. For every command, say the verdict out loud the way a findings report would: control, expected value, observed value, pass or fail. The labs cis-core-dumps, cis-cron-hardening, cis-filesystem-modules, cis-network-params and security-tls-crypto-policy each start from a failing host and grade the files exactly the way these checks read them.
grep -E '^[[:space:]]*\*[[:space:]]+hard[[:space:]]+core' /etc/security/limits.conf; su - student -c 'ulimit -Hc'; grep -rh suid_dumpable /etc/sysctl.d/ /etc/sysctl.confCore dumps: the hard-limit line, its effect in a new login, and every place fs.suid_dumpableis set. Pass is* hard core 0,0, and a singlefs.suid_dumpable = 0.Runnable in the cis-cron-hardening room — that room’s setup plants the files it reads
stat -c '%a %U:%G %n' /etc/crontab /etc/cron.d; ls -l /etc/cron.allow /etc/cron.deny /etc/at.allow 2>&1cron: modes on the config, then the access files. Pass is 600 and 700, cron.allowandat.allowpresent,cron.denyabsent.for m in cramfs freevxfs udf usb-storage; do printf '%s: ' "$m"; modprobe -n -v "$m" 2>&1; doneModules: a dry run for each CIS filesystem module. Pass is install /bin/false(or/bin/true). On this container,not foundmeans no install line exists yet.systemd-analyze cat-config sysctl.d | grep -E '^-?net\.ipv4\.(conf\.(all|default|\*)\.(accept_redirects|send_redirects|accept_source_route|log_martians|rp_filter)|icmp_echo_ignore_broadcasts)'Network sysctls in apply order. For each key the last line printed is the value the host boots with. Runnable in the security-tls-crypto-policy room — that room’s setup plants the files it reads
grep -m1 -n '^ *\[' /etc/ssl/openssl.cnf; grep -nE '^ *(openssl_conf|ssl_conf|system_default|MinProtocol|CipherString) *=' /etc/ssl/openssl.cnfTLS: the first line prints the first [header];openssl_confmust have a smaller line number. Then follow the chain and check the policy section setsMinProtocolto TLSv1.2 or higher and aSECLEVELof 2 or more.
- A CIS control has two halves: the persistent line in the right file (what the scanner reads and what survives a reboot) and the effective value you read back with the tool that applies it.
- Core dumps:
* hard core 0in limits.conf (checked with ulimit -c in a NEW login shell;*skips root),fs.suid_dumpable = 0in /etc/sysctl.d, andStorage=nonein /etc/systemd/coredump.conf. - cron and at: if cron.allow exists it alone decides and cron.deny is ignored; with only a deny file it's a blocklist. Keep cron.allow / at.allow, delete the deny files, chmod 600 /etc/crontab and 700 the /etc/cron.* directories. On Ubuntu, cron.allow is root:crontab 640.
- Modules:
install <mod> /bin/falsestops every load;blacklist <mod>only stops alias autoloading. Verify with modprobe -n -v <mod> and modprobe --showconfig. - sysctl.d files apply in file-name order and the last assignment wins, so name the CIS drop-in to sort late (60- beats Ubuntu's 10- and 50- files). sysctl --system re-applies everything in boot order; sysctl -p FILE applies one file.
- OpenSSL reads its policy through openssl_conf (global section only) -> ssl_conf -> system_default -> MinProtocol / CipherString @SECLEVEL. Prove it with OPENSSL_CONF and a stricter probe; on RHEL use update-crypto-policies.
| Control | Setting | File | Verify |
|---|---|---|---|
| Core dumps (limit) | * hard core 0 | /etc/security/limits.conf | su - user -c 'ulimit -Hc' |
| Core dumps (setuid) | fs.suid_dumpable = 0 | /etc/sysctl.d/*.conf | sysctl -n fs.suid_dumpable |
| Core dumps (systemd) | Storage=none | /etc/systemd/coredump.conf | systemd-analyze cat-config systemd/coredump.conf |
| cron / at access | allow file present, deny file removed | /etc/cron.allow, /etc/at.allow | su - user -c 'crontab -l' |
| cron config | 600 / 700, root-owned | /etc/crontab, /etc/cron.* | stat -c '%a %U:%G %n' |
| Filesystem modules | install <mod> /bin/false + blacklist <mod> | /etc/modprobe.d/*.conf | modprobe -n -v <mod> |
| Network parameters | redirects 0, source route 0, martians 1, rp_filter 1 | /etc/sysctl.d/*.conf | systemd-analyze cat-config sysctl.d, sysctl -n |
| TLS floor | MinProtocol = TLSv1.2, @SECLEVEL=2 | /etc/ssl/openssl.cnf | OPENSSL_CONF probe; update-crypto-policies --show on RHEL |
