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

Current implementation of nftables rules breaks Wireguard service on CentOS 7 #389

Open
Rebelllious opened this issue Apr 17, 2023 · 6 comments

Comments

@Rebelllious
Copy link
Contributor

Apr 17 15:33:06 wireguard.home wg-quick[14278]: Warning: `/etc/wireguard/wg0.conf' is world accessible
Apr 17 15:33:06 wireguard.home wg-quick[14278]: [#] ip link add wg0 type wireguard
Apr 17 15:33:06 wireguard.home NetworkManager[848]: <info>  [1681759986.3219] manager: (wg0): new WireGuard device (/org/freedesktop/NetworkManager/Devices/4)
Apr 17 15:33:06 wireguard.home wg-quick[14278]: [#] wg setconf wg0 /dev/fd/63
Apr 17 15:33:06 wireguard.home wg-quick[14278]: [#] ip -4 address add 10.0.0.1/8 dev wg0
Apr 17 15:33:06 wireguard.home wg-quick[14278]: [#] ip -6 address add fd00:00:00::1/8 dev wg0
Apr 17 15:33:06 wireguard.home wg-quick[14278]: [#] ip link set mtu 1420 up dev wg0
Apr 17 15:33:06 wireguard.home wg-quick[14278]: [#] sysctl --write net.ipv4.ip_forward=1; sysctl --write net.ipv6.conf.all.forwarding=1; nft add table inet wireguard-wg0; nft add chain inet wireguard-wg0 wireguard_chain {type nat hook post
routing priority srcnat\; policy accept\;}; nft add rule inet wireguard-wg0 wireguard_chain oifname ens192 masquerade
Apr 17 15:33:06 wireguard.home wg-quick[14278]: net.ipv4.ip_forward = 1
Apr 17 15:33:06 wireguard.home wg-quick[14278]: net.ipv6.conf.all.forwarding = 1
Apr 17 15:33:06 wireguard.home wg-quick[14278]: Error: syntax error, unexpected string, expecting - or number
Apr 17 15:33:06 wireguard.home wg-quick[14278]: add chain inet wireguard-wg0 wireguard_chain {type nat hook postrouting priority srcnat; policy accept;}
Apr 17 15:33:06 wireguard.home wg-quick[14278]: ^^^^^^
Apr 17 15:33:06 wireguard.home NetworkManager[848]: <info>  [1681759986.3816] device (wg0): state change: unmanaged -> unavailable (reason 'connection-assumed', sys-iface-state: 'external')
Apr 17 15:33:06 wireguard.home wg-quick[14278]: [#] ip link delete dev wg0
Apr 17 15:33:06 wireguard.home systemd[1]: wg-quick@wg0.service: main process exited, code=exited, status=1/FAILURE
Apr 17 15:33:06 wireguard.home systemd[1]: Failed to start WireGuard via wg-quick(8) for wg0.
-- Subject: Unit wg-quick@wg0.service has failed
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
--
-- Unit wg-quick@wg0.service has failed.
--
-- The result is failed.
Apr 17 15:33:06 wireguard.home systemd[1]: Unit wg-quick@wg0.service entered failed state.
Apr 17 15:33:06 wireguard.home systemd[1]: wg-quick@wg0.service failed.
Apr 17 15:33:06 wireguard.home polkitd[9321]: Unregistered Authentication Agent for unix-process:14272:179239 (system bus name :1.35, object path /org/freedesktop/PolicyKit1/AuthenticationAgent, locale en_US.UTF-8) (disconnected from bus)
Apr 17 15:33:06 wireguard.home NetworkManager[848]: <info>  [1681759986.4995] keyfile: add connection /var/run/NetworkManager/system-connections/wg0.nmconnection (e421d624-f43a-4865-a16f-b1681b3cceae,"wg0")
Apr 17 15:33:06 wireguard.home NetworkManager[848]: <info>  [1681759986.5140] device (wg0): state change: unavailable -> disconnected (reason 'connection-assumed', sys-iface-state: 'external')
Apr 17 15:33:06 wireguard.home NetworkManager[848]: <info>  [1681759986.5156] device (wg0): Activation: starting connection 'wg0' (e421d624-f43a-4865-a16f-b1681b3cceae)
Apr 17 15:33:06 wireguard.home NetworkManager[848]: <info>  [1681759986.5175] device (wg0): state change: disconnected -> unmanaged (reason 'unmanaged', sys-iface-state: 'removed')

This might be related to too low version of nftables available in CentOS 7 (0.8.14, which is about 5 years old as of now).

@Prajwal-Koirala
Copy link
Member

I'm ready to assist with the WireGuard issue you're encountering. Here's a breakdown of the information you've provided and potential steps to address it:

Error Analysis:

  • nftables Syntax Error: The primary error is a syntax error in the nft command used to configure network rules for WireGuard. It's likely due to an outdated nftables version (0.8.14) on CentOS 7.
  • wg-quick Service Failure: This service, responsible for managing WireGuard interfaces, fails to start due to the nftables error.

Potential Solutions:

  1. Upgrade nftables (Recommended):

    • If possible, upgrade nftables to a newer version that supports the required syntax. This is often the most reliable solution.
    • Check for available updates using your package manager (e.g., yum update nftables).
    • If updates are unavailable, consider alternative methods below.
  2. Adjust wg-quick Configuration:

    • If upgrading nftables isn't feasible, you might be able to modify the wg-quick configuration to avoid the problematic nft command.
    • This might involve using alternative firewall rules or adjusting WireGuard settings.
    • Consult WireGuard documentation or community forums for guidance on specific configuration changes.
  3. Consider Alternative Firewall Solutions:

    • If the issue persists, explore using a different firewall solution that aligns better with the older nftables version.
    • iptables, for example, might be more compatible in this case.

Additional Troubleshooting:

  • Check wg0.conf Permissions: Ensure the /etc/wireguard/wg0.conf file has appropriate permissions to avoid the "world accessible" warning.
  • Review NetworkManager Logs: Examine NetworkManager logs for further insights into the issue.

Next Steps:

  1. Choose the most suitable approach based on your system constraints and preferences.
  2. If you're uncertain about specific steps, provide more details about your environment and configuration for tailored guidance.
  3. I'm here to assist further as you troubleshoot and work towards a resolution.

@Prajwal-Koirala
Copy link
Member

Certainly! If you're looking to enhance the setup of your WireGuard VPN on a Raspberry Pi, particularly focusing on the nftables configuration for improved functionality or security, here are several suggestions. These improvements could make your setup more robust, efficient, or tailored to specific needs:

1. General Improvements

  • Ensure Persistence: Ensure your sysctl configurations for IP forwarding persist across reboots. You can do this by adding net.ipv4.ip_forward = 1 and net.ipv6.conf.all.forwarding = 1 to /etc/sysctl.conf or a dedicated file under /etc/sysctl.d/.

  • Logging: Consider adding logging rules to your nftables setup to monitor denied packets or other events. This can be invaluable for debugging and security monitoring. For example, before your masquerade rule, you could add a logging rule for packets that will be masqueraded.

2. Specific nftables Enhancements

  • Refined Masquerading: If you have multiple outbound interfaces (e.g., eth0 for wired connections) and want to masquerade based on the source or destination, you can add conditions to your masquerade rule. For instance, you might want different masquerade rules for wlan0 and eth0.

  • Interface-independent Masquerading: Instead of hardcoding wlan0, consider using conditions that don't depend on the interface name. This can make your rules more flexible if your interface names change (though less specific):

    nft add rule inet wireguard-wg0 wireguard_chain ip saddr {YOUR_VPN_NETWORK_RANGE} masquerade
    

    Replace {YOUR_VPN_NETWORK_RANGE} with your WireGuard VPN's subnet, ensuring that only traffic from your VPN is masqueraded.

  • Forwarding and Security Rules: Beyond NAT, ensure your setup includes necessary forwarding and security rules. For instance, you might want to block certain inbound or outbound traffic on the VPN interface for security purposes.

3. Performance Considerations

  • Conntrack Tweaks: If you're expecting high volumes of traffic, consider tuning nf_conntrack settings to optimize performance and avoid dropped connections due to table overflow. This involves adjusting settings like nf_conntrack_max and nf_conntrack_buckets in your sysctl configuration.

4. Security Enhancements

  • Default Drop Policy: For both security and performance, consider setting a default drop policy on your input and forward chains and only allow necessary traffic. Explicitly allowing traffic can significantly improve security.

  • Rate Limiting: To protect against certain types of denial-of-service (DoS) attacks, consider adding rate limiting to your inbound connections.

Applying the Suggestions

Here's an improved version of your nftables setup incorporating some of these suggestions, focusing on masquerading and logging:

# Create the table
nft add table inet wireguard-wg0

# Add the NAT chain
nft add chain inet wireguard-wg0 wireguard_chain { type nat hook postrouting priority srcnat \; }

# Optional: Add a logging rule for debugging or monitoring (adjust log prefix as needed)
# nft add rule inet wireguard-wg0 wireguard_chain oifname "wlan0" log prefix "WireGuard NAT: " 

# Masquerade packets from the VPN
nft add rule inet wireguard-wg0 wireguard_chain ip saddr {YOUR_VPN_NETWORK_RANGE} oifname "wlan0" masquerade

Remember, these improvements are starting points. Tailor them to your network's specific requirements and constraints, and always test changes in a controlled environment before deploying them to production.

@Prajwal-Koirala
Copy link
Member

Sure, diving deeper into configuring your WireGuard setup with nftables, focusing on subnets, ports, and additional enhancements, will ensure a robust, secure, and efficient VPN. Let's expand on the configuration by integrating subnet and port considerations and exploring further improvements.

Understanding Subnets and Ports in WireGuard Context

  1. Subnets: WireGuard interfaces are usually associated with a particular subnet that defines the IP address range available for VPN clients. For instance, if your WireGuard server is configured on a 10.0.0.1/24 subnet, it can accommodate clients with IP addresses ranging from 10.0.0.1 to 10.0.0.254.

  2. Ports: WireGuard listens on a specific UDP port (the default is 51820) for incoming connections. Ensuring that this port is open and correctly managed in your firewall rules is crucial for the operation of your VPN.

Advanced nftables Configuration

Building upon the initial setup, let's consider subnet and port management, alongside additional security measures:

Subnet-specific Rules

  • Isolating VPN Traffic: Ensure that only traffic from your VPN's subnet can be forwarded or masqueraded. This prevents unauthorized access and ensures that your VPN traffic is properly routed.

    nft add rule inet wireguard-wg0 wireguard_chain ip saddr {VPN_SUBNET} oifname "wlan0" masquerade
    

    Replace {VPN_SUBNET} with your actual VPN subnet, e.g., 10.0.0.0/24.

Port Management

  • Allowing VPN Connection: Specifically allow incoming UDP traffic on your WireGuard port to ensure clients can connect.

    nft add rule inet wireguard-wg0 wireguard_chain udp dport {WG_PORT} accept
    

    Replace {WG_PORT} with your WireGuard listening port, typically 51820.

Additional Improvements

  1. Enhanced Security Rules:

    • Implement stateful firewall rules to allow established connections and related packets, while blocking unsolicited traffic. This can significantly improve security.
    nft add rule inet wireguard-wg0 wireguard_chain ct state established,related accept
    nft add rule inet wireguard-wg0 wireguard_chain ct state invalid drop
    
  2. Forwarding Rules:

    • Explicitly allow forwarding from your VPN subnet to the desired networks or the internet, while blocking others. This granular control ensures that only authorized traffic can pass through your VPN.
    # Assuming a separate chain for forward rules exists
    nft add rule inet wireguard-wg0 forward_chain ip saddr {VPN_SUBNET} ip daddr {ALLOWED_DESTINATION} accept
    
  3. Rate Limiting:

    • Implement rate limiting for new connections to mitigate potential DoS attacks. This is particularly important for the WireGuard listening port.
    nft add rule inet wireguard-wg0 wireguard_chain udp dport {WG_PORT} limit rate over {RATE}/second burst {BURST} packets drop
    

    Replace {RATE} and {BURST} with appropriate values, e.g., 10/second and 20 packets.

  4. Logging and Monitoring:

    • Increase visibility into your network traffic by logging specific events or all dropped packets. This can aid in troubleshooting and detecting potential security issues.

Implementing the Enhancements

Incorporating these suggestions requires careful planning and a clear understanding of your network's layout and security requirements. Adjust the rules to fit your specific subnet ranges, interface names, and desired security posture. Remember to replace placeholders like {VPN_SUBNET}, {WG_PORT}, {ALLOWED_DESTINATION}, {RATE}, and {BURST} with actual values relevant to your setup.

Testing and Validation

After applying these improvements, thoroughly test your VPN configuration to ensure that it operates as expected. Validate that the VPN can handle client connections securely and efficiently, and that the routing and firewall rules are correctly applied.

By taking these steps, you'll enhance the security, performance, and flexibility of your WireGuard VPN, providing a more robust solution for your network.

@Prajwal-Koirala
Copy link
Member

While the functionality of the provided commands might be sufficient for basic WireGuard operation, there are ways to improve them in terms of security and clarity:

1. Use dedicated firewall rules:

Instead of relying on the broad "masquerade" rule, it's recommended to create specific rules that allow only authorized traffic through the WireGuard tunnel. This enhances security by minimizing the attack surface and ensuring only required traffic gets routed through the VPN.

2. Specify allowed protocols:

Currently, the rule doesn't specify allowed protocols, meaning it allows any type of traffic (TCP, UDP, etc.) through the tunnel. It's good practice to explicitly list the protocols used by your WireGuard connection, typically UDP.

3. Document the configuration:

Adding comments to the commands can significantly improve readability and maintainability. Briefly explaining the purpose of each command would be helpful for future reference or anyone reviewing the configuration.

Here's an example of how the commands could be improved:

# Enable IP forwarding for IPv4 and IPv6
sysctl --write net.ipv4.ip_forward=1
sysctl --write net.ipv6.conf.all.forwarding=1

# Create a dedicated NFT table for WireGuard
nft add table inet wireguard-wg0

# Create a chain for NAT within the table
nft add chain inet wireguard-wg0 wireguard_chain { type nat hook postrouting priority srcnat }

# Allow only UDP traffic through the WireGuard tunnel
nft add rule inet wireguard-wg0 wireguard_chain udp dport <port_number> oifname wlan0 masquerade

# Add comments explaining the purpose of each command
# ...

Remember, these are general improvements, and the specific configuration might vary depending on your individual setup and security requirements. Consult the official WireGuard documentation and NFtables resources for further guidance on secure and tailored configurations.

@Prajwal-Koirala
Copy link
Member

Let's refine your nftables configuration for the WireGuard VPN on your Raspberry Pi. The goal is to enhance security, efficiency, and specificity in your firewall rules. Below, I've incorporated improvements to your setup, including a more nuanced approach to handling subnets and ports, as well as bolstering security measures.

Improved Configuration

  1. Create a Dedicated Table and Chains
# Create the table
nft add table inet wireguard-wg0

# Add the NAT chain for masquerading
nft add chain inet wireguard-wg0 postrouting { type nat hook postrouting priority srcnat \; }

# Add a forward chain for handling forwarding rules
nft add chain inet wireguard-wg0 forward { type filter hook forward priority 0 \; }

# Add an input chain for direct communications to the Raspberry Pi
nft add chain inet wireguard-wg0 input { type filter hook input priority 0 \; }
  1. Masquerading for VPN Subnet

Replace {VPN_SUBNET} with your actual VPN subnet (e.g., 10.0.0.0/24).

# Masquerade packets from the VPN
nft add rule inet wireguard-wg0 postrouting ip saddr {VPN_SUBNET} oifname "wlan0" masquerade
  1. Specific Traffic Rules

Replace <port_number> with your WireGuard listening port (e.g., 51820). The directive to only allow UDP traffic through the WireGuard tunnel's specific port is somewhat redundant if the masquerade rule already exists and is correctly set up since masquerading applies to outgoing traffic. Instead, focus on filtering incoming WireGuard connections and managing forwarded traffic.

# Allow WireGuard UDP traffic on the listening port
nft add rule inet wireguard-wg0 input udp dport <port_number> accept
  1. Enhanced Security Rules

Enhancements include better stateful inspection and dropping of invalid packets, as well as a clear distinction between what is allowed and what is dropped.

# Accept established and related connections
nft add rule inet wireguard-wg0 input ct state established,related accept
nft add rule inet wireguard-wg0 forward ct state established,related accept

# Drop invalid packets
nft add rule inet wireguard-wg0 input ct state invalid drop
nft add rule inet wireguard-wg0 forward ct state invalid drop
  1. Forwarding Rules

Replace {VPN_SUBNET} with your VPN's subnet and {ALLOWED_DESTINATION} with the specific subnet(s) you wish to allow VPN clients to access. If you're allowing access to the internet, this rule might not be necessary as masquerading takes care of routing traffic out.

# Allow forwarding from VPN subnet to specific destinations
nft add rule inet wireguard-wg0 forward ip saddr {VPN_SUBNET} ip daddr {ALLOWED_DESTINATION} accept

# Optionally, drop all other forwarding requests not matched by previous rules
nft add rule inet wireguard-wg0 forward ip saddr {VPN_SUBNET} drop

Additional Notes

  • Reviewing Rule Order: The order of rules in nftables is significant. Ensure that more specific rules precede more general ones. This setup starts with masquerading rules, followed by specific allowances for incoming connections, then manages stateful connections, and finally, drops invalid packets.

  • Subnet Specification: Be precise with your subnets to ensure only intended traffic is allowed. Mistakes here can inadvertently expose your network.

  • Testing: After applying these rules, test your setup thoroughly. Check both connectivity through the VPN and that the security restrictions behave as expected.

  • Persistence: Remember to save your nftables configuration to ensure it persists across reboots. You can typically do this with nft list ruleset > /etc/nftables.conf (depending on your distribution).

This refined setup provides a more detailed, secure, and flexible approach to managing your WireGuard VPN traffic with nftables.

@Prajwal-Koirala
Copy link
Member

Sure, I'll provide a consolidated and final version of the refined nftables configuration for your WireGuard VPN setup. This version includes all the suggested improvements for security, efficiency, and management of traffic through your VPN. Remember to replace placeholders like {VPN_SUBNET}, <port_number>, and {ALLOWED_DESTINATION} with your actual configuration values.

Final nftables Configuration for WireGuard

# Create the table for WireGuard
nft add table inet wireguard-wg0

# Add a NAT chain for masquerading outgoing VPN traffic
nft add chain inet wireguard-wg0 postrouting { type nat hook postrouting priority srcnat \; }
nft add rule inet wireguard-wg0 postrouting ip saddr {VPN_SUBNET} oifname "wlan0" masquerade

# Add a forward chain for managing VPN traffic forwarding
nft add chain inet wireguard-wg0 forward { type filter hook forward priority 0 \; }

# Allow forwarding from VPN to specific allowed destinations
nft add rule inet wireguard-wg0 forward ip saddr {VPN_SUBNET} ip daddr {ALLOWED_DESTINATION} accept
# Drop any other forwarding not explicitly allowed
nft add rule inet wireguard-wg0 forward ip saddr {VPN_SUBNET} drop

# Add an input chain for direct WireGuard VPN traffic to the Raspberry Pi
nft add chain inet wireguard-wg0 input { type filter hook input priority 0 \; }
# Allow WireGuard UDP traffic on the VPN port
nft add rule inet wireguard-wg0 input udp dport <port_number> accept
# Accept established and related connections to the Pi
nft add rule inet wireguard-wg0 input ct state established,related accept
# Drop invalid packets
nft add rule inet wireguard-wg0 input ct state invalid drop

# Enhanced security for forwarded traffic
# Accept established and related connections for forwarding
nft add rule inet wireguard-wg0 forward ct state established,related accept
# Drop invalid forwarded packets
nft add rule inet wireguard-wg0 forward ct state invalid drop

Instructions:

  • Replace Placeholders:

    • {VPN_SUBNET} with your VPN's subnet, like 10.0.0.0/24.
    • <port_number> with your WireGuard server's listening port, typically 51820.
    • {ALLOWED_DESTINATION} with the subnet you wish VPN clients to access, e.g., your local network 192.168.1.0/24 or 0.0.0.0/0 for internet access.
  • Apply Configuration: Enter these commands in your terminal on the Raspberry Pi. Each line configures a part of the nftables setup for your WireGuard VPN.

  • Save Configuration: Ensure your nftables setup persists across reboots. You can usually save the current configuration with:

    nft list ruleset > /etc/nftables.conf

This setup should provide a robust, secure foundation for managing VPN traffic, applying NAT masquerading for outgoing traffic, and ensuring only authorized access to and through your VPN. Always test thoroughly after applying new firewall rules to ensure they meet your network's needs without disrupting service.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants