Postfix Connection Error: Fixing “No such file or directory” for OpenDKIM Unix Socket


4 views

When migrating Postfix servers, a common pitfall is the OpenDKIM socket connection failure. The error message:

warning: connect to Milter service unix:/var/run/opendkim/opendkim.sock: No such file or directory

typically indicates one of several potential configuration problems between Postfix and OpenDKIM.

First, verify the socket's existence and permissions:

ls -la /var/run/opendkim/opendkim.sock
srwxrwxr-x 1 opendkim opendkim 0 Aug 14 15:11 /var/run/opendkim/opendkim.sock

Key things to check:

  • The socket file actually exists (your output shows it does)
  • Postfix has permission to access the directory and socket
  • The socket hasn't been deleted by a service restart

Here are the most effective fixes for this issue:

1. AppArmor/SELinux Restrictions

Security modules might be blocking access. Check logs:

grep avc /var/log/audit/audit.log | grep opendkim
dmesg | grep apparmor

2. User/Group Permissions

Ensure Postfix can access the socket:

usermod -a -G opendkim postfix
chmod 750 /var/run/opendkim
chown opendkim:opendkim /var/run/opendkim/opendkim.sock

3. Socket Path Consistency

Verify these configurations match exactly:

# In /etc/opendkim.conf
Socket local:/var/run/opendkim/opendkim.sock

# In /etc/postfix/main.cf
smtpd_milters = unix:/var/run/opendkim/opendkim.sock

When the basic fixes don't work, try these advanced steps:

Force Socket Recreation

systemctl stop opendkim
rm -f /var/run/opendkim/opendkim.sock
systemctl start opendkim

Test Socket Communication

nc -U /var/run/opendkim/opendkim.sock
HELO example.com
QUIT

Here's a complete working configuration for reference:

# /etc/opendkim.conf
Mode            sv
Socket          local:/var/run/opendkim/opendkim.sock
PidFile         /var/run/opendkim/opendkim.pid
UserID          opendkim:opendkim
Umask           002
KeyTable        /etc/opendkim/key.table
SigningTable    refile:/etc/opendkim/signing.table
ExternalIgnoreList  /etc/opendkim/trusted.hosts
InternalHosts       /etc/opendkim/trusted.hosts

And the matching Postfix configuration:

# /etc/postfix/main.cf
milter_default_action = accept
milter_protocol = 2
smtpd_milters = unix:/var/run/opendkim/opendkim.sock
non_smtpd_milters = $smtpd_milters

For systems using systemd, create this override file:

# /etc/systemd/system/opendkim.service.d/override.conf
[Service]
RuntimeDirectory=opendkim
RuntimeDirectoryMode=0750

Then reload systemd:

systemctl daemon-reload
systemctl restart opendkim postfix

The classic Unix socket visibility problem strikes again. Here's what we know:

ls -la /var/run/opendkim/
srwxrwxr-x 1 opendkim opendkim 0 Aug 14 15:11 /var/run/opendkim/opendkim.sock

Yet Postfix stubbornly claims:

warning: connect to Milter service unix:/var/run/opendkim/opendkim.sock: No such file or directory

This typically happens due to one of these scenarios:

  1. The Postfix process runs in a different mount namespace (common with systemd)
  2. The socket permissions don't allow Postfix to access it
  3. The socket path has changed between service restarts

First, verify the socket existence from Postfix's perspective:

sudo -u postfix ls -la /var/run/opendkim/opendkim.sock

If that fails, check for mount namespace isolation:

sudo ls -la /proc/$(pgrep -f "postfix/master")/ns/mnt
sudo ls -la /proc/$(pgrep -f "opendkim")/ns/mnt

Solution 1: Use abstract namespace socket

# In opendkim.conf
Socket local:/var/run/opendkim/opendkim.sock
# becomes
Socket local:@opendkim

Solution 2: Shared directory with correct permissions

sudo mkdir -p /var/spool/postfix/opendkim
sudo chown opendkim:postfix /var/spool/postfix/opendkim
sudo chmod 750 /var/spool/postfix/opendkim

# In opendkim.conf
Socket local:/var/spool/postfix/opendkim/opendkim.sock

# In main.cf
smtpd_milters = unix:/var/spool/postfix/opendkim/opendkim.sock

For systems using systemd, create this override:

sudo systemctl edit opendkim

[Service]
ReadWritePaths=/var/spool/postfix/opendkim
PrivateTmp=false

When all else fails, switch to TCP:

# opendkim.conf
Socket inet:8892@localhost

# main.cf
smtpd_milters = inet:localhost:8892

Remember to adjust your firewall rules accordingly.

After making changes:

sudo systemctl restart opendkim postfix
sudo tail -f /var/log/mail.log

Look for successful Milter connection messages in the logs.