Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

systemd service hardening for pcscd #207

Open
davidfields opened this issue Aug 27, 2024 · 6 comments
Open

systemd service hardening for pcscd #207

davidfields opened this issue Aug 27, 2024 · 6 comments
Assignees

Comments

@davidfields
Copy link

davidfields commented Aug 27, 2024

I was curious if systemd service hardening had been discussed within this project, so I searched and came across an email [1] from June 2019 (also the to-do list [2]). I understand this may be a low-priority, but I thought I would contribute what I can.

Below is a drop-in configuration for pcscd.service that I have been using for a couple of months. For ease of reference, I have listed the directives in the order that they appear in the systemd.exec man page [3].

My distro is Arch. My pcsc-lite is from the Arch official repos, and I update my system frequently so the version would be whatever is there at any given time. The same would be true of any other relevant software. The only smartcards I currently have access to and have used with this are various Yubikey 5 series. My workflow as it relates to testing functionality is fairly limited. I mainly use Yubikey PIV with OpenSSH via PKCS#11 (opensc-pkcs11).

(I originally wrote this using trial and error, and while doing the same for a handful of other services.)

[Service]
# Paths
ProtectProc=invisible

# Capabilities
CapabilityBoundingSet=

# Security
NoNewPrivileges=yes

# Process Properties
UMask=0077

# Sandboxing
ProtectSystem=strict
ProtectHome=yes
PrivateTmp=yes
#PrivateDevices=yes
PrivateNetwork=yes
#PrivateIPC=yes
PrivateUsers=yes
ProtectHostname=yes
ProtectClock=yes
ProtectKernelTunables=yes
ProtectKernelModules=yes
ProtectKernelLogs=yes
ProtectControlGroups=yes
RestrictAddressFamilies=~AF_INET AF_INET6
RestrictNamespaces=yes
LockPersonality=yes
MemoryDenyWriteExecute=yes
RestrictRealtime=yes
RestrictSUIDSGID=yes
#RemoveIPC=yes
#PrivateMounts=yes

# System Call Filtering
SystemCallFilter=@system-service
SystemCallFilter=~@resources @privileged
SystemCallArchitectures=native

The commented out directives are ones that, when I wrote this a few months ago, I had either tested and they definitely caused things to break, or I had not yet tested.

Looking at the commented out directives now:

  • PrivateDevices=yes definitely causes things to break (for I think obvious reasons)
  • PrivateIPC=yes does not immediately cause things to break
  • RemoveIPC=yes does not immediately cause things to break
  • PrivateMounts=yes does not immediately cause things to break

There are some other directives that I am deliberately ignoring for now, such as User= or DynamicUser=, as well as directives that lock down the paths for various things. I am ignoring them not because they are unimportant (they are important), but because I think, if there is interest, we could make progress by first getting some of the easier ones out of the way...

Additionally, there is likely room to further lock down RestrictAddressFamilies= and SystemCallFilter=.

I will also note that some of these hardening directives may not currently do anything while the service runs as root. Off the top of my head, I believe this is the case for ProtectProc=invisible and RemoveIPC=yes.

systemd-analyze security pcscd.service gives an exposure score of "9.6 UNSAFE 😨" for the unhardened service, which as of now we bring down to "1.4 OK 🙂".

I believe there is an issue that may be caused by one (or more) of these directives. When I remove my Yubikey and plug it back in, it stops working until I restart pcscd.service. I then also restart my ssh-agent.service, and then begin using it as normal again. I quickly tested by reverting to no hardening directives, and this does not happen. I might have to spend some time narrowing this down...

All that being said, if there is interest in hardening pcscd.service, I think it would be helpful if others could take a look and test functionality on their systems. I would be happy to fix whatever is needed and submit a pull request once we arrive at something that is stable.

Please let me know if anyone has any thoughts, comments, issues, etc.

I would also like to thank the maintainers and contributors for their work on pcsc-lite.

[1] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=930530

[2] https://salsa.debian.org/rousseau/PCSC/-/issues/10

[3] https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html

@davidfields
Copy link
Author

When I remove my Yubikey and plug it back in, it stops working until I restart pcscd.service.

I think the culprit for this was PrivateNetwork=yes. After changing it to PrivateNetwork=no, I have not been able to reproduce that problem so far.

there is likely room to further lock down RestrictAddressFamilies=

I replaced RestrictAddressFamilies=~AF_INET AF_INET6 with RestrictAddressFamilies=AF_UNIX AF_NETLINK, which also works for me so far.

@LudovicRousseau
Copy link
Owner

Sorry for the delay. I missed your messages.

Hardening pcscd is fine.
But it may be difficult because pcscd does not know what services are required by the drivers it will load.
Some drivers (like https://frankmorgner.github.io/vsmartcard/virtualsmartcard/README.html) will use the network for example.

@migrgh
Copy link

migrgh commented Jan 16, 2025

Since systemd pcscd run as root which is the main reason to restrict it i guess and systemd make it possible.

One security option i missed is the following which only allow specific executables.
You could go down more if you add all the needed libs instead of the whole directory.

Anyway i want to share it as i also hardening my running pcscd on my own.

NoExecPaths=/
ExecPaths=/usr/lib64/ /usr/sbin/pcscd

Minimal add beside ProtectProc=invisible you also could add is:
ProcSubset=pid

LudovicRousseau added a commit to LudovicRousseau/PCSC-devel that referenced this issue Jan 18, 2025
See https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html

Thanks to David Fields for the initial patch
"systemd service hardening for pcscd"
LudovicRousseau/PCSC#207
@LudovicRousseau
Copy link
Owner

I pushed LudovicRousseau/PCSC-devel@5f7ed01 in the PCSC-devel repository.

We will need more testers, in particular people using non-standard drivers.

@CoelacanthusHex
Copy link

I pushed LudovicRousseau/PCSC-devel@5f7ed01 in the PCSC-devel repository.

We will need more testers, in particular people using non-standard drivers.

Please don't use PrivateNetwork=true, it will make pcscd broken with udev because it will block AF_NETLINK message from host which is used by systemd-udevd. Their document informs this especially:

       PrivateNetwork=
           Takes a boolean argument. If true, sets up a new network namespace for the executed processes and configures only the loopback network device "lo" inside it. No other network devices will be available to the executed process. This is useful to turn off
           network access by the executed process. Defaults to false. It is possible to run two or more units within the same private network namespace by using the JoinsNamespaceOf= directive, see systemd.unit(5) for details. Note that this option will disconnect all
           socket families from the host, including AF_NETLINK and AF_UNIX. Effectively, for AF_NETLINK this means that device configuration events received from systemd-udevd.service(8) are not delivered to the unit's processes. And for AF_UNIX this has the effect
           that AF_UNIX sockets in the abstract socket namespace of the host will become unavailable to the unit's processes (however, those located in the file system will continue to be accessible).

LudovicRousseau added a commit to LudovicRousseau/PCSC-devel that referenced this issue Jan 19, 2025
See https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html

Thanks to David Fields for the initial patch
"systemd service hardening for pcscd"
LudovicRousseau/PCSC#207
@LudovicRousseau
Copy link
Owner

LudovicRousseau added a commit to LudovicRousseau/PCSC-devel that referenced this issue Jan 19, 2025
See https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html

The exposure level was:
$ systemd-analyze security pcscd.service
[...]
→ Overall exposure level for pcscd.service: 9.6 UNSAFE 😨

And we now have:
$ systemd-analyze security pcscd.service
[...]
→ Overall exposure level for pcscd.service: 2.1 OK 🙂

Thanks to David Fields for the initial patch
"systemd service hardening for pcscd"
LudovicRousseau/PCSC#207
LudovicRousseau added a commit to LudovicRousseau/PCSC-devel that referenced this issue Jan 25, 2025
See https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html

The exposure level was:
$ systemd-analyze security pcscd.service
[...]
→ Overall exposure level for pcscd.service: 9.6 UNSAFE 😨

And we now have:
$ systemd-analyze security pcscd.service
[...]
→ Overall exposure level for pcscd.service: 2.1 OK 🙂

Thanks to David Fields for the initial patch
"systemd service hardening for pcscd"
LudovicRousseau/PCSC#207
LudovicRousseau added a commit to LudovicRousseau/PCSC-devel that referenced this issue Feb 4, 2025
See https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html

The exposure level was:
$ systemd-analyze security pcscd.service
[...]
→ Overall exposure level for pcscd.service: 9.6 UNSAFE 😨

And we now have:
$ systemd-analyze security pcscd.service
[...]
→ Overall exposure level for pcscd.service: 2.1 OK 🙂

Thanks to David Fields for the initial patch
"systemd service hardening for pcscd"
LudovicRousseau/PCSC#207
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants