Giter Site home page Giter Site logo

Comments (31)

jodevsa avatar jodevsa commented on September 13, 2024 1

Suppose, that this variant is even better. But it depends on my own flow. Which resources are created first. If there is a chance to use not IP: 8.8.8.8, but namespace: Alice, then it will completely resolve my issue.

Filtering by namespace is a complex task so I'm thinking of delivering this feature in multiple phases to break the work in smaller chunks and make delivery possible

initial plan:

  • egress rules for destination IP (Phase 1)
apiVersion: vpn.example.com/v1alpha1
kind: WireguardPeer
metadata:
  name: peer1
spec:
  wireguardRef: "my-cool-vpn"
  networkPolicy:
    egress:
     - action: Allow 
        destination:
            IP: 8.8.8.8
  • egress rules based on kubernetes service (Phase 2)
apiVersion: vpn.example.com/v1alpha1
kind: WireguardPeer
metadata:
  name: peer1
spec:
  wireguardRef: "my-cool-vpn"
  networkPolicy:
    egress:
     - action: Allow 
        destination:
            service:
                 service: "service-1"
                 namespace: "A"
  • egress rules based on namespace (phase3)
apiVersion: vpn.example.com/v1alpha1
kind: WireguardPeer
metadata:
  name: peer1
spec:
  wireguardRef: "my-cool-vpn"
  networkPolicy:
    egress:
     - action: Allow 
        namespace: "A"

from wireguard-operator.

jodevsa avatar jodevsa commented on September 13, 2024 1

Oh, I mean create namespace and a service in that namespace with an explicitly set IP address.

So probably phase 1 will cover your case (I know it's not convenient but I hope this will unblock you):

apiVersion: vpn.example.com/v1alpha1
kind: WireguardPeer
metadata:
name: peer1
spec:
wireguardRef: "my-cool-vpn"
networkPolicy:
egress:
- action: Allow
destination:
IP: 8.8.8.8

from wireguard-operator.

UrfinJuice11 avatar UrfinJuice11 commented on September 13, 2024 1

Hi,

Thanks for the output.

This bug is now fixed and I also added a test for that. Please install the main branch again: https://raw.githubusercontent.com/jodevsa/wireguard-operator/main/release.yaml

Hi, yes. The solution is working well!

  1. Creating a peer with a predefined allowed IP address.
  2. Creating a pod for this peer with this address in clusterIP
  3. The peer can see only this IP.

Thank you!

from wireguard-operator.

jodevsa avatar jodevsa commented on September 13, 2024

Hi @UrfinJuice11,

I'll write more info soon but will leave a quick hint now:

You'll need to create 2 Wireguard server instances. One called "A" on namespace "A" and another called "B" on namespace "B". if you want a user to only connect to namespace A then create a peer for them on wireguard server A and then create a network policy that makes sure wireguard A only can speak with pods in namespace A

from wireguard-operator.

UrfinJuice11 avatar UrfinJuice11 commented on September 13, 2024

I am afraid this is not a solution for my case, since I am going to have tens or hundereds of clients.
But thanks for your reply.

from wireguard-operator.

jodevsa avatar jodevsa commented on September 13, 2024

are you available for a quick chat about it?

from wireguard-operator.

jodevsa avatar jodevsa commented on September 13, 2024

can you join:
https://meet.google.com/bii-vnud-mhp?authuser=0&pli=1
?

from wireguard-operator.

UrfinJuice11 avatar UrfinJuice11 commented on September 13, 2024

What about a solution, where access controls are implemented not at the CNI level, but at the WG server level?
For example, we create a wireguardpeer instance with smth like allowed_destination_ip definition in yaml (don't mess with allowedIPs in WG config). Then while creating a record in server's wg0.conf this allowed_destination_ip value will be written in PreUP declaration with an iptables rule.
Since services in different namespaces have different IP-addresses, we can use these addresses to differentiate clients' flows.

So, can the feature request be to have custom definitions of PreUp, PostUp and etc. in wg0.conf in wireguard instance yaml. (I tried to add them to the appropriate secret, but the secret was not rewritten)

Also, a question. Is there any means of manual changing config file for WG server?

from wireguard-operator.

jodevsa avatar jodevsa commented on September 13, 2024

sounds good! so your only interested in allowing each peer to access a couple of k8s services?

if you need the WireguardPeer to be able to access a whole namespace then you somehow need to collect all the IPs in namespace, which continuously changes. pod IPs are not namespace identifiable (there is no way of knowing which namespace this pod IP belongs to). I'm still trying to figure out how the Calico CNI does iptable rules based on namespaces.. I suspect that these rules only apply to the worker of the source or the destination pod but not both as this is the only way to implement such control without having to keep a list of all ips in a namespace.

The idea of keeping a list of all IPs in a namespace is not that crazy and we could bake that inside wireguard-operator. k8s already something similar; If you look at how k8s services are implemented you will see that they rely on storing a list of IPs that matches tha service label. the list of IPs is stored in the endpoints resource can be examined using kubectl get endpoints

from wireguard-operator.

UrfinJuice11 avatar UrfinJuice11 commented on September 13, 2024

My situation is the following:

image

Even now my project can be alive, if there will be a way to mention PostUp iptables rules while creating wireguardpeers. But at this setup I need to:

  1. create the wireguardpeer with some IPs (or maybe IP range, like 10.0.0.0/30) in PostUp rules.
  2. only then create the Alice namespace and explicitly create her services on the mentioned IP or IP ranges.

This variant is good for me because the Alice's pod will be alive for a short period of time. And all I need is a way to add PostUp and PostDown rules to [Peer] sections of wireguardpeer. Is it possible to add this functionality?

But, I suppose that this solution will cover only my scenario, and in order to make wireguard-operator more universal, the trick with endpoints and DNS-names should be more reasonable.

from wireguard-operator.

jodevsa avatar jodevsa commented on September 13, 2024

Thanks for the explanation and the diagram.

This variant is good for me because the Alice's pod will be alive for a short period of time. And all I need is a way to add PostUp and PostDown rules to [Peer] sections of wireguardpeer. Is it possible to add this functionality?

Can you give me an example of what iptable command you will be running in PostUp and PostDown of the peer section?

from wireguard-operator.

jodevsa avatar jodevsa commented on September 13, 2024

I think you'll need to use the peer IP in the iptable rule so we probably need to expose it as an enviroment variable so that your postUp/postDown script can use it

from wireguard-operator.

jodevsa avatar jodevsa commented on September 13, 2024

I'm thinking of something like this; what do you think?

apiVersion: vpn.example.com/v1alpha1
kind: WireguardPeer
metadata:
  name: peer1
spec:
  wireguardRef: "my-cool-vpn"
  postUp: "iptables -I OUTPUT --source $PEER_IP -d  8.8.8.8 -j DROP"

$PEER_IP is an enviroment variable that will be populated with the actual peer IP

from wireguard-operator.

jodevsa avatar jodevsa commented on September 13, 2024

another idea that involves some abstractions similar to the ones in NetworkPolicy

apiVersion: vpn.example.com/v1alpha1
kind: WireguardPeer
metadata:
  name: peer1
spec:
  wireguardRef: "my-cool-vpn"
  networkPolicy:
    egress:
     - action: Allow 
        destination:
            IP: 8.8.8.8

I like this more as it would be easier for the average user and doesn't need expertise in iptables. We also need to implement an implicit DENY all behaviour similar to the behaviour of GlobalNetworkPolicy/NetworkPolicy.

Does implementing something like this cover your case?

from wireguard-operator.

UrfinJuice11 avatar UrfinJuice11 commented on September 13, 2024

Yes, that's exactly I am talking about.

So, the wg0.conf of the server will be smth. like:

PrivateKey = <server-private-key>
Address = 10.0.0.1/24
ListenPort = <server-port>

[Peer]
PublicKey = <peer1-public-key>
AllowedIPs = 10.0.0.2/32, 192.168.0.2/32
PostUp = iptables -A FORWARD -i wg0 -o eth0 -s 10.0.0.2/32 -d 192.168.0.2/32 -j ACCEPT

[Peer]
PublicKey = <peer2-public-key>
AllowedIPs = 10.0.0.3/32, 192.168.0.3/32
PostUp = iptables -A FORWARD -i wg0 -o eth0 -s 10.0.0.3/32 -d 192.168.0.3/32  -j ACCEPT

But also there should be the contraversal operation like PostDown in order to delete the rules after the peer is dead.

Now, I should think by myself what would be the workflow in my case. I mean if the peer config is created before namespace, than there are no problems, because I can get the destination address 192.168.0.2/32 or 192.168.0.2/30 with kubectl get wireguardpeer and create the namespace with that address.

Anyway it is my own problem. But. I think that adding the PreUp, PostUp, PreDown, PostDown, Address, AllowedIPs sections to the wireguardpeer yaml would be good in any practical case.

from wireguard-operator.

UrfinJuice11 avatar UrfinJuice11 commented on September 13, 2024

another idea that involves some abstractions similar to the ones in NetworkPolicy

apiVersion: vpn.example.com/v1alpha1
kind: WireguardPeer
metadata:
  name: peer1
spec:
  wireguardRef: "my-cool-vpn"
  networkPolicy:
    egress:
     - action: Allow 
        destination:
            IP: 8.8.8.8

I like this more as it would be easier for the average user and doesn't need expertise in iptables. We also need to implement an implicit DENY all behaviour similar to the behaviour of GlobalNetworkPolicy/NetworkPolicy.

Does implementing something like this cover your case?

Suppose, that this variant is even better. But it depends on my own flow. Which resources are created first. If there is a chance to use not IP: 8.8.8.8, but namespace: Alice, then it will completely resolve my issue.

from wireguard-operator.

jodevsa avatar jodevsa commented on September 13, 2024

and create the namespace with that address.

What do you mean by that?

from wireguard-operator.

UrfinJuice11 avatar UrfinJuice11 commented on September 13, 2024

Oh, I mean create namespace and a service in that namespace with an explicitly set IP address.

from wireguard-operator.

jodevsa avatar jodevsa commented on September 13, 2024

phase 1 implementation ideas:

We'll probably rely on iptables-restore to apply new rules every time a Peer is updated. The logic should be idempotent and does not cause any downtime while updating the iptables rules. The operator should inject the iptables rules into the pod of the wireguard server that would look like something like this:

*filter

# rules for peer 10.8.0.2
:10.8.0.2 - [0:0]
-A FORWARD -s 10.8.0.2/32 -j 10.8.0.2
-A 10.8.0.2 -d 10.8.0.1/32 -j ACCEPT
-A 10.8.0.2 -d 100.64.0.10/32 -j ACCEPT
-A 10.8.0.2 -j REJECT --reject-with icmp-port-unreachable

# rules for peer 10.8.0.3
:10.8.0.3 - [0:0]
-A FORWARD -s 10.8.0.3/32 -j 10.8.0.3
-A 10.8.0.3 -d 10.8.0.1/32 -j ACCEPT
-A 10.8.0.3 -d 100.64.0.10/32 -j ACCEPT -m comment --comment "include the json of this rule for debugging purposes"
-A 10.8.0.3 -j REJECT --reject-with icmp-port-unreachable -m comment --comment "implicit reject all"

COMMIT

*nat
:PREROUTING ACCEPT [4234:819045]
:INPUT ACCEPT [14:2125]
:OUTPUT ACCEPT [345:23125]
:POSTROUTING ACCEPT [347:23299]
-A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
COMMIT

iptables-restore seems to be the only way to update the rules in an atomic fashion

from wireguard-operator.

jodevsa avatar jodevsa commented on September 13, 2024

more insights about iptables and how to update rules in an atomic way: https://isawan.net/posts/atomic-iptables-script

from wireguard-operator.

jodevsa avatar jodevsa commented on September 13, 2024

Hi @UrfinJuice11,

I have good news; I'm done with phase 1 #28; it still needs some cleaning but the feature works!! hopefully I'll merge it in the next days

from wireguard-operator.

jodevsa avatar jodevsa commented on September 13, 2024

here is how the config looks like

spec:
  PrivateKeyRef:
    secretKeyRef:
      key: privateKey
      name: peer20-peer
  address: 10.8.0.2
  egressNetworkPolicies:
  - action: Accept
    protocol: UDP
    to:
      ip: 8.8.8.8
      port: "53"
  - action: Accept
    protocol: TCP
    to:
      ip: 202.78.174.252
      port: "6443"

from wireguard-operator.

jodevsa avatar jodevsa commented on September 13, 2024

feature is merged; I didn't officially release it yet but you can try it by installing this https://raw.githubusercontent.com/jodevsa/wireguard-operator/main/release.yaml

let me know what do you think

from wireguard-operator.

UrfinJuice11 avatar UrfinJuice11 commented on September 13, 2024

Thanks a lot! I'll check it this weekend.

Now can not run the wg-deployment

image

from wireguard-operator.

jodevsa avatar jodevsa commented on September 13, 2024

What do you mean?
Can you send me the output of

kubectl get secret wapt-wg --template={{.data.iptable}} | base64 -d

from wireguard-operator.

jodevsa avatar jodevsa commented on September 13, 2024

btw, why are you deploying wireguard on the wireguard-system namespace? This namespace is supposed to only have the wireguard-operator components and not the actual wireguard server

from wireguard-operator.

jodevsa avatar jodevsa commented on September 13, 2024

I think wireguard-system.svc.cluster.local does not exist.. you probably need something like wapt-wg.wireguard-system.svc.cluster.local. Again, I do not recommend to use wireguard-system namespace.

from wireguard-operator.

UrfinJuice11 avatar UrfinJuice11 commented on September 13, 2024

I think wireguard-system.svc.cluster.local does not exist.. you probably need something like wapt-wg.wireguard-system.svc.cluster.local. Again, I do not recommend to use wireguard-system namespace.

Now created wg server in separate namespace: wapt-wg

The error remains

image

*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
COMMIT

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
# start of rules for peer 10.8.0.2
:10-8-0-2 - [0:0]
-A FORWARD -s 10.8.0.2 -j 10-8-0-2
-A 10-8-0-2 -d 172.20.0.5 -p icmp -j ACCEPT
-A 10-8-0-2 -d 10.8.0.2 -j ACCEPT
-A 10-8-0-2 -d 10.96.0.10, wapt-wg.svc.cluster.local -p UDP --dport 53 -j ACCEPT
-A 10-8-0-2 -d 10.13.37.1 -p TCP --dport 9090 -j ACCEPT
-A 10-8-0-2 -j REJECT --reject-with icmp-port-unreachable
# end of rules for peer 10.8.0.2
COMMIT

from wireguard-operator.

jodevsa avatar jodevsa commented on September 13, 2024

Hi,

Thanks for the output.

This bug is now fixed and I also added a test for that.
Please install the main branch again: https://raw.githubusercontent.com/jodevsa/wireguard-operator/main/release.yaml

from wireguard-operator.

jodevsa avatar jodevsa commented on September 13, 2024

great to hear that. let me know if you need anything else :)

from wireguard-operator.

jodevsa avatar jodevsa commented on September 13, 2024

i'll close this issue since you seem to be unblocked now

from wireguard-operator.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.