Configure Host-based and User-based Security for the Service on RHEL 7

Security for SSH, HTTP/S, DNS, NFS, SMB and SMTP.

Host-based Security

Host-based security will be configured on an application level and not on a firewall.

Our aim is to configure access control as follows:

  1. Allow from: *.rhce.local (10.8.8.0/24),
  2. Deny from: my1337.hacker.local (10.8.9.99/32).

SSH

Allow firewall SSH access for all:

# firewall-cmd --permanent --add-service=ssh

Open /etc/hosts.deny and add the following:

sshd:   my1337.hacker.local

Open /etc/hosts.allow and add the following:

sshd:   *.rhce.local

By default everything is allowed.

# journalctl -xlf
[...]
sshd[3069]: refused connect from my1337.hacker.local (10.8.9.99)

HTTP/HTTPS (Apache)

Allow firewall HTTP/S access for all:

# firewall-cmd --permanent --add-service={http,https}

Put the following into the httpd configuration file:

<RequireAll>
  Require host rhce.local
  Require not host my1337.hacker.local
</RequireAll>
# journalctl -xlf
[...]
[authz_core:error] [pid 3057] [client 10.8.9.99:43378] AH01630: client denied by server configuration: /var/www/html/

DNS (Unbound)

Allow firewall DNS access for all:

# firewall-cmd --permanent --add-service=dns

Open /etc/unbound/unbound.conf and add the following line:

access-control: 10.8.8.0/24 allow

By default everything is refused.

NFS

Allow firewall NFS access for all:

# firewall-cmd --permanent --add-service=nfs

Open /etc/exports and configure access:

/nfs *.rhce.local(ro)

Everything else is refused.

SMB

Allow firewall SMB access for all:

# firewall-cmd --permanent --add-service=samba

Open /etc/samba/smb.conf and configure hosts allow entries:

hosts allow = 10.8.8.

The hosts deny list can also be used, but note that where the lists conflict, the allow list takes precedence.

SMTP (Postfix)

Allow firewall SMTP access for all:

# firewall-cmd --permanent --add-service=smtp

Open /etc/postfix/access and add the following:

rhce.local          OK
my1337.hacker.local REJECT

Run:

# postmap /etc/postfix/access

Add the following line to /etc/postfix/main.cf:

smtpd_client_restrictions = check_client_access hash:/etc/postfix/access
# journalctl -xlf
[...]
postfix/smtpd[3939]: connect from my1337.hacker.local[10.8.9.99]
postfix/smtpd[3939]: NOQUEUE: reject: RCPT from my1337.hacker.local[10.8.9.99]: 554 5.7.1 <my1337.hacker.local[10.8.9.99]>: Client host rejected: Access denied; from=<[email protected]> to=<[email protected]> proto=ESMTP helo=
postfix/smtpd[3939]: disconnect from my1337.hacker.local[10.8.9.99]
[...]
postfix/smtpd[3939]: connect from srv1.rhce.local[10.8.8.71]
postfix/smtpd[3939]: A075621186: client=srv1.rhce.local[10.8.8.71]
postfix/cleanup[3944]: A075621186: message-id=<[email protected]>
postfix/qmgr[3882]: A075621186: from=<[email protected]>, size=610, nrcpt=1 (queue active)
postfix/smtpd[3939]: disconnect from srv1.rhce.local[10.8.8.71]
postfix/local[3946]: A075621186: to=<[email protected]>, relay=local, delay=0.08, delays=0.06/0.01/0/0.01, dsn=2.0.0, status=sent (delivered to mailbox)
postfix/qmgr[3882]: A075621186: removed

User-based Security

SSH

Open /etc/ssh/sshd_config and configure the following sections:

AllowUsers sandy
DenyUsers root

Don’t forget to restart the sshd service.

HTTP/HTTPS (Apache)

Open /etc/httpd/conf/httpd.conf and configure user authentication:

<Directory "/var/www/html">
   AuthType Basic
   AuthName "Login Required"
   AuthUserFile "/etc/httpd/conf/htpasswd"
   Require valid-user
</Directory>

You will need to create a password file with a valid user:

# htpasswd -c /etc/httpd/conf/htpasswd sandy

Don’t forget to restart the httpd service.

NFS

NFS server does not require authentication and only enforces access restrictions that are based on IP addresses or host names of a client. Using the default security method, which is sec=sys, the NFS server trusts any uid that is sent by the client.

Kerberos should be used to prove user identity.

SMB

Open /etc/samba/smb.conf and configure the following sections:

valid users = sandy, alice
write list = alice
read list = sandy

The valid users is a list of users that should be allowed to login to this service.

The write list is a list of users that are given read-write access to a service. If the connecting user is in this list then they will be given write access, no matter what the read only option is set to.

Don’t forget to restart the smb service.

SMTP (Postfix)

Postfix’s per-address access control /etc/postfix/access:

[email protected] REJECT

17 thoughts on “Configure Host-based and User-based Security for the Service on RHEL 7

  1. Hello Tomas,
    Which part of httpd.conf block should be placed to? If I put it into the end, Apache says “not allowed here”.
    Googling did no help

  2. if anything of the above does not work, you can use firewalld rich rules:

    firewall-cmd –permanent –add-rich-rule=’rule family=ipv4 source address=10.39.91.67 invert=”True” service name=http reject’
    this is how to allow access to web server only from a particular host

    • It’s a weird way of creating a firewalld rich rule, isn’t it simpler to allow traffic for http service rather than invert the “reject”?

      # firewall-cmd --add-rich-rule='rule family=ipv4 source address=10.39.91.67/32 service name=http accept'
    • yep, sure, it is. I did not think about it because 1. I do initial services conficuration allowing all traffic 2. tune their security. I could just remove the “allow all http” rule and add this one.
      By the way, tcpwrappers hosts.allow hosts.deny work for sshd, but not for httpd. So, I had to use firewalld or restrict access via Vhost.conf

    • You can surely use firewalld to restrict access to a virtual host, but how about a scenario, where you have to create two virtual hosts on the same TCP port, but one available for the world, and one available for a specific IP only? You cannot do that with firewalld, that’s where host-based security comes into play.

    • The option should be specified not in the end of the config, but right after PermitRootLogin – fixed

  3. SSH: DenyUsers vince – does not work for the LDAP user (( . I specisy it in the very end of sshd_config. the service was restarted, of course

    • It seems to work fine in my test environment:

      ipa.rhce.local sshd[3107]: refused connect from server1.rhce.local (10.8.8.71)

      I suggest you check your DNS records, ensure they are OK, plus make sure that pointer records for IPs are set up.

  4. for this question: shouldn’t we do just the deny part
    Allow from: *.rhce.local (10.8.8.0/24),
    Deny from: my1337.hacker.local (10.8.9.99/32).
    from what I understand if *.rhce.local is not mentioned in hosts.deny then server will accept the connection by default? I am little concerned about this question, mainly because if you have hosts.deny and hosts.allow entries server will read those two files and ignore connections from any other domain.
    Sorry for making this complicated. does this make sense?

    • To be honest, it doesn’t matter whether you use one file or both, as log as access is configured properly (either allowed or denied, depending on a question). Stick to whatever is easier for you.

  5. Yesterday I realized the purpose of the and blocks.Here is an example where you want all connections comming from localhost to be allowed and anything outside it – to be authenticated as user rbowen.So RequireAll directive requires everything to be ok,on the contrary requireany – if you match 1 rule you are authenticated.The example speaks for itself:

    Require local

    AuthType Basic
    AuthName “Restricted Files”
    AuthBasicProvider file
    AuthUserFile “/usr/local/apache/passwd/passwords”
    Require user rbowen

  6. Want to clear something up: when configuring host based access for httpd, you have the following:

    Require host rhce.local
    Require not host my1337.hacker.local

    Though in your original directions, it says you want enable all connections from the “rhce.local” domain. My question is this:

    Shouldn’t it be:

    Require host *.rhce.local
    Require not host my1337.hacker.local

    Where you have the * to represent the wildcard (Similar to how it’s set up in the /etc/host.deny file)?

    Also, may be getting in the weeds a bit, but outside of internal networks, is it practical to filter hostnames prevent access over internet? Let’s say there’s a bad website, and I don’t want anyone on that domain to access my website.

    I’m thinking no, because of NAT/IP Masquerading (The hostname doesn’t appear when the webserver receives an incoming connection) and your hosting company DNS records would already blacklist that IP schema/hostnames (Or, at the very least, someone would use their online tools to blacklist/whitelist hostnames), but just wanted to make sure.

  7. Hi,
    In the SSH User-based Security example above, “AllowUsers sandy” will automatically deny access from all other users except user “sandy”. Therefore, “DenyUsers root” is not really required.

    • It isn’t required in this particular case, however, it’s good to know the options available in case you are asked to deny access to one user only (and allow everything else).

Leave a Reply

Your email address will not be published. Required fields are marked *