Categories
DSSP2

Leveraging Secmark on Agnus for termy.id

I have a login shell account on my Agnus host that I basically use for shared confined shell access. It is not quite a minimal login shell but not far from it. The user can connect with Termy as well as SSH with SFTP access, it has a systemd –user instance, and it has access to emacs, git client, screen.

Emacs and git can optionally be used to connect to the network, but I did not want that to be an all-or-nothing proposition. So I decided to leverage Secmark so that Emacs Termy instance (Eww) can be used to browse “allowed_web” and so that Git client Termy instance can be used to connect to “allowed_git” (this only includes Git access via git:// an https:// — so no ssh:// access). Also DNS access is restricted to “allowed_dns”. Local DNS is currently “allowed_dns”, defensec.nl is currently “allowed_web” and “allowed_git”. So Termy can use Emacs Eww to browse this blog , and git can be used to access the dssp2.git repositories. I can easily manage the “allowed_web”, “allowed_git”, and “allowed_dns” hosts. And I might extend Emacs access to for example mail with “allowed_mail”, IRC “allowed_irc”, etc.

The mysecmark.cil policy module that I use for this:

(block allowed_dns (blockinherit net.packet.obj_template))
(block allowed_git (blockinherit net.packet.obj_template))
(block allowed_web (blockinherit net.packet.obj_template))

(typeattribute secmark_constrained_subj_type_attribute)
(typeattributeset secmark_constrained_subj_type_attribute (emacs.termy.subj git.client.termy.subj screen.termy.subj termy_server.termy.subj systemd.termy.subj emacs.client.termy.subj passwd.termy.subj))

(typeattribute dns_client_minus_secmark_constrained_type_attribute)
(typeattributeset dns_client_minus_secmark_constrained_type_attribute (and dns.client_subj_type_attribute (not secmark_constrained_subj_type_attribute)))

(call sys.invalid.packet_send (dns_client_minus_secmark_constrained_type_attribute))
(call sys.invalid.packet_recv (dns_client_minus_secmark_constrained_type_attribute))

(call allowed_dns.packet_recv (dns.client_subj_type_attribute))
(call allowed_dns.packet_send (dns.client_subj_type_attribute))

(call allowed_git.packet_recv (dns.client_subj_type_attribute))
(call allowed_git.packet_send (dns.client_subj_type_attribute))

(call allowed_web.packet_recv (dns.client_subj_type_attribute))
(call allowed_web.packet_send (dns.client_subj_type_attribute))

(call sys.invalid.dontaudit_packet_recv (secmark_constrained_subj_type_attribute))
(call sys.invalid.dontaudit_packet_send (secmark_constrained_subj_type_attribute))

The /etc/sysconfig/nftables.secmark configuration I use for this:

table inet mysecmark {

    secmark allowed_dns {
        "sys.id:sys.role:allowed_dns.packet:s0"
    }

    secmark allowed_git {
        "sys.id:sys.role:allowed_git.packet:s0"
    }

    secmark allowed_web {
        "sys.id:sys.role:allowed_web.packet:s0"
    }

    map secmapping4_out {
        type ipv4_addr . inet_service : secmark
        elements = { 192.168.1.1 . 53 : "allowed_dns", 80.100.19.56 . 9418 : "allowed_git", 80.100.19.56 . 80 : "allowed_web", 80.100.19.56 . 443 : "allowed_web" }
    }

    map secmapping6_out {
        type ipv6_addr . inet_service : secmark
        elements = { fd18:5480:168d::1 . 53 : "allowed_dns", 2001:985:d55d::711 . 9418 : "allowed_git", 2001:985:d55d::711 . 80 : "allowed_web", 2001:985:d55d::711 . 443 : "allowed_web" }
    }

    chain input {
        type filter hook input priority -225;

        # label new incoming packets and add to connection
        ct state new ct secmark set meta secmark

        # set label for est/rel packets from connection
        ct state established,related meta secmark set ct secmark
    }

    chain output {
        type filter hook output priority 225;

        # label new outgoing packets and add to connection
        ct state new meta secmark set ip daddr . tcp dport map @secmapping4_out
        ct state new meta secmark set ip daddr . udp dport map @secmapping4_out
        ct state new meta secmark set ip6 daddr . tcp dport map @secmapping6_out
        ct state new meta secmark set ip6 daddr . udp dport map @secmapping6_out
        ct state new ct secmark set meta secmark

        # set label for est/rel packets from connection
        ct state established,related meta secmark set ct secmark
    }
}

The /etc/systemd/system/nftables.secmark.service I use for this:

# /etc/systemd/system/nftables.secmark.service
[Unit]
Description=Netfilter Tables
Documentation=man:nft(8)
Wants=network-pre.target
Before=network-pre.target

[Service]
Type=oneshot
ProtectSystem=full
ProtectHome=true
ExecStart=/sbin/nft -f /etc/sysconfig/nftables.secmark
ExecReload=/sbin/nft 'flush table inet mysecmark; include "/etc/sysconfig/nftables.secmark";'
ExecStop=/sbin/nft flush table inet mysecmark
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

1 reply on “Leveraging Secmark on Agnus for termy.id”

Leave a Reply

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