google cloud platform – Kubernetes managing many distinct UDP servers on GKE

I’m trying to set up a system that can automatically spin up and down video game servers as docker images. In this case, factoriotools/factorio-docker. Each game is a different, distinct single-pod deployment of that container, and therefore (in the simplified case) needs its own IP address that can listen on a specific UDP port. Load balancers are redundant and irrelevant, and Cloud NAT doesn’t appear to allow ingress traffic easily.

There’s a couple ways I know of to get this to work, both with pretty major compromises:

  • I can use a NodePort service, and lose control over which port the client needs to connect to. That’s an issue because the server registers itself with a server listing.
  • I can use host networking. If my information is correct, that requires privileged containers, which is Definitely Not Good.
  • I could maybe use a UDP load balancer, but even if that exists and works, it’s expensive.

There are probably ways to work around the limitations of either approach (for the second, keep the hosts short-lived and keep the firewall strict, and it should be mostly OK?), but I can’t help but think there’s a better option that I can’t find described in the official kubernetes docs. Does traefik have some trick I don’t know about? Is there some way to get a variant of MetalLB that can dynamically allocate public IP addresses as I need them?

How do I get each server-container to listen on a different public IP address with a specific UDP port, without making security impossible in the process?

Why should one expect a ~30% drop in speed when using OpenVPN UDP?

https://support.nordvpn.com/Connectivity/1047408902/Speed-and-bandwidth.htm (mirror) mentions:

If you are connected to the closest available server through OpenVPN UDP, you can expect around a 30% drop in speed.

Why should one expect a 30% drop in speed when using OpenVPN UDP? Protocol overhead? Some other reasons?

Should I use UDP or TCP for logging to a SIEM?

We have an application that runs on hundreds of users’ computers on our company’s internal network. We want to start sending logs from this app to a SIEM (Graylog). We have decided to add code to our app that sends logs from the app to the SIEM directly. The only question is, should we use UDP or TCP to send the logs? My preference is to use TCP because of the reliability, but what happens if the SIEM goes offline — won’t that cause our app to block, thus slowing down our entire system? I am very curious about how other companies handle this situation. I have read a few guides online, and most recommend TCP because of the reliability but none address the blocking issue.

linux – Using nftables to drop UDP packets on a random basis

I have an iptables rule that I use to drop UDP packets on a random basis. I’m trying to convert this to nftables, but I’m likely making a syntax error, because nftables complains that the “dport” argument is unexpected.

Here’s my iptables rule: iptables -A INPUT -m statistic --mode random --probability 0.10 -p udp --destination-port 2020 -i eth0 -j DROP

I tried using iptables-translate but I get the same rule back:

$ iptables-translate -A INPUT -m statistic --mode random --probability 0.10 -p udp  --destination-port 2020 -i eth0  -j DROP
nft # -A INPUT -m statistic --mode random --probability 0.10 -p udp --destination-port 2020 -i eth0 -j DROP

I tried to create my own nftables table, chain and rule using:

$ sudo nft add table ip filter
$ sudo nft add chain ip filter mychain

But when I try to use the rule, I get the error that dport is unexpected:

$ sudo nft add rule ip filter mychain input udp dport 2020 drop
Error: syntax error, unexpected dport, expecting end of file or newline or semicolon
add rule ip filter mychain input udp dport 2020 drop
                                     ^^^^^          
  1. What am I doing wrong?
  2. Why can’t iptables-translate translate this rule?

Allow UDP connection only if a TCP connection was made before

I’m trying to figure out how can I allow UDP connections on a port only if a TCP connection was made before, I’ve tried rcheck, but no luck.

thread safety – Java UDP port knocking authentication. Many clients at the same time

Student project of mine i got 4/5 points but i suspect theres a lot of weird stuff in there. I never had a chance to hear my teacher feedback about it and it bothers me so i figured out somebody could take a glance at it please and provide some feedback.

Quick documentation https://pastebin.com/9W1Jhf77

Server:

package com.company;

import java.io.IOException;
import java.net.*;
import java.util.*;
import java.util.stream.Collectors;

public class Server implements Runnable{
    byte() buffer = new byte(2048);
    byte() sendBuffer = new byte(2048);

    List<DatagramSocket> socketList;
    Map<InetSocketAddress, List<Integer>> internalMap;
    Map<InetSocketAddress, List<Integer>> guestMap;
    List<Integer> key;

    Server(Integer... ports) throws SocketException {
        this.key = new ArrayList<>();
        //key.addAll(Arrays.asList(ports));
        for(Integer portnumber : ports)
            key.add(portnumber);

        this.socketList = new ArrayList<>();
        this.internalMap = new HashMap<>();
        this.guestMap = Collections.synchronizedMap(internalMap);

        List<Integer> uniquePorts = key.stream().distinct().collect(Collectors.toList());

        for(Integer port: uniquePorts){
            DatagramSocket socket = new DatagramSocket(port);
            socketList.add(socket);
        }

        System.out.println("Zajete porty: ");
        socketList.forEach(n -> System.out.print(n.getLocalPort() + ", "));
        System.out.println();


        this.key = socketList.stream().map(DatagramSocket::getLocalPort).collect(Collectors.toList());
    }


    @Override
    public void run() {

        for(DatagramSocket socket : socketList){
            Thread t = new Thread(){
                boolean running;
                @Override
                public void run() {

                    while(true){
                        DatagramPacket packet = new DatagramPacket(buffer, buffer.length);

                        try {
                            socket.receive(packet);
                            ProtocolMessage msgRecvd = new ProtocolMessage(packet.getData());
                            System.out.println(msgRecvd); //dbgging
                            if(!msgRecvd.equals(Protocol.synMessage))
                                throw new ProtocolException("Request not recognized, possibly malformed");

                            InetAddress address = packet.getAddress();
                            int port = packet.getPort();
                            InetSocketAddress guest = new InetSocketAddress(address,port);


                            if(guestMap.containsKey(guest)){
                                guestMap.get(guest).add(socket.getLocalPort());   //refactor it later

                                if(guestMap.get(guest).equals(key)){
                                    ServerClientService serverClientService = new ServerClientService();
                                    int establishedPort = serverClientService.serverSocket.getLocalPort();
                                    System.out.println("Guest: " + address + ":" + port+ " authenticated sending tcp port: " + establishedPort);

                                    ProtocolMessage auth = Protocol.authSuccess;
                                    auth.setValue(establishedPort);
                                    sendBuffer = auth.toByte();
                                    socket.send(new DatagramPacket(sendBuffer,sendBuffer.length, address, port));

                                    serverClientService.run();
                                }

                                else if(key.size() < guestMap.get(guest).size()){
                                    guestMap.remove(guest);
                                }
                            }

                            else{
                                List<Integer> list = new ArrayList<>();
                                List<Integer> synchlist = Collections.synchronizedList(list);
                                synchlist.add(socket.getLocalPort());
                                guestMap.put(guest, synchlist);
                            }

                            sendBuffer = Protocol.ackMessage.toByte();
                            DatagramPacket confirmation = new DatagramPacket(sendBuffer, sendBuffer.length, address, port);
                            socket.send(confirmation);

                        }catch (SocketTimeoutException e){
                            e.printStackTrace();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }

                }
            };
            t.setDaemon(true);  //inne wątki nie moga istniec bez procesu main
            t.start();

        }

        Scanner s = new Scanner(System.in);
        System.out.println("Naciśnij "Enter" aby wyjść.....");
        s.nextLine();
    }

}

Server-Client TCP service:

package com.company;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerClientService implements Runnable {
    ServerSocket serverSocket;

    ServerClientService(){
        try {
            serverSocket = new ServerSocket(0);
        } catch (IOException e) {
            e.printStackTrace();
            System.err.println("Port niedostepny");
        }
    }

    @Override
    public void run() {
        try(    Socket clientSocket = serverSocket.accept();
                PrintWriter out = new PrintWriter(clientSocket.getOutputStream());
                BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()))
        )
        {
            String query = in.readLine();
            System.out.println(query);
            String response = "hello there client " + getPort();
            out.println(response);
            out.flush();


            serverSocket.close();

        } catch (IOException e) {
            e.printStackTrace();
        }


    }

    public int getPort() {
        return serverSocket.getLocalPort();
    }
}

Client:

package com.company;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.*;
import java.util.ArrayList;
import java.util.List;

public class Client {
    byte() sendBuffer;
    byte() recvBuffer;
    DatagramSocket socket;
    String hostName;

    List<Integer> key;


    Client(String address, int... ports) throws SocketException {
        this.key = new ArrayList<>();
        this.sendBuffer = new byte(2048);
        this.recvBuffer = new byte(2048);
        this.socket = new DatagramSocket();
        this.hostName = address;
        for(int i : ports)
            this.key.add(i);
    }

    public void run() {
        try {
            InetAddress inetAddress = InetAddress.getByName(hostName);
            for(Integer port : key){

                sendBuffer = Protocol.synMessage.toByte();
                DatagramPacket packet = new DatagramPacket(sendBuffer, sendBuffer.length, inetAddress,port);
                socket.send(packet);
                //System.out.println("sent: " + new ProtocolMessage(sendBuffer));

                DatagramPacket returnPacket = new DatagramPacket(recvBuffer, recvBuffer.length);
                returnPacket.setLength(returnPacket.getLength());
                socket.setSoTimeout(5000);
                try {
                    socket.receive(returnPacket);
                } catch (SocketTimeoutException e){
                    System.err.println("No response, probably invalid authentication");
                }
                ProtocolMessage response = new ProtocolMessage(returnPacket.getData());
                System.out.println(response); //debugging

                if (response.equals(Protocol.ackMessage)) {
                    //proceed
                    continue;
                }
                else if(response.equals(Protocol.authSuccess)){
                    //connect to sent tcp port
                    int portNumber = response.value;
                    startTcpConnection(portNumber);
                    break;
                }

                else{
                    throw new ProtocolException("Response not recognized, possibly malformed");
                    //should like catch it and try again perhaps
                }

            }


        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        socket.close();

    }

    public void startTcpConnection(int port ){
        try(Socket tcpSocket = new Socket(hostName, port);
            PrintWriter out = new PrintWriter(tcpSocket.getOutputStream());
            BufferedReader in = new BufferedReader(new InputStreamReader(tcpSocket.getInputStream()));)
        {

            out.println("Client " + port + ": hello");
            out.flush();
            String response = in.readLine();
            System.out.println(response);


        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}

Common protocol:

package com.company;

public class Protocol {
    final static ProtocolMessage synMessage = new ProtocolMessage(1);
    final static ProtocolMessage ackMessage = new ProtocolMessage(2);
    final static ProtocolMessage authSuccess = new ProtocolMessage(3);

}
package com.company;

import java.nio.ByteBuffer;

public class ProtocolMessage {
    int type;
    int value;

    ProtocolMessage(int type, int value){
        this.type = type;
        this.value = value;
    }
    ProtocolMessage(int type){
        this.type = type;
        this.value = 0;
    }
    ProtocolMessage(byte() bytes){
        ByteBuffer wrapped = ByteBuffer.wrap(bytes);
        this.type = wrapped.getInt(0);
        this.value = wrapped.getInt(50);
    }

    public byte() toByte(){
        ByteBuffer byteBuffer = ByteBuffer.allocate(2048);
        byteBuffer.putInt(0,this.type);
        byteBuffer.putInt(50,this.value);

        return byteBuffer.array();
    }

    @Override
    public String toString(){
        return type + ":" + value;
    }

    @Override
    public boolean equals(Object o){
        ProtocolMessage another = (ProtocolMessage) o;
        if(another.type == this.type)
            return true;
        else
            return false;
    }

    void setValue(int value){
        this.value = value;
    }
}

vpn – OpenVPN: UDP broadcast in tap environment

Background: I am currently trying to create a VPN for playing old computer games via LAN (Empire Earth / Warcraft III) and to bypass geo-blocks.

I am using the docker image by kylemanna and my openvpn.conf is the following:

server 10.13.37.0 255.255.255.0
verb 3
key /etc/openvpn/pki/private/<censored>.key
ca /etc/openvpn/pki/ca.crt
cert /etc/openvpn/pki/issued/<censored>.crt
dh /etc/openvpn/pki/dh.pem
tls-auth /etc/openvpn/pki/ta.key
key-direction 0
keepalive 10 60
persist-key
persist-tun

proto udp
# Rely on Docker to do port mapping, internally always 1194
port 1194
dev tap0
status /tmp/openvpn-status.log

user nobody
group nogroup
client-to-client
comp-lzo no

### Route Configurations Below
route 192.168.254.0 255.255.255.0

### Push Configurations Below
push "block-outside-dns"
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"
push "comp-lzo no"

### Extra Configurations Below
topology subnet

For accessing the internet using the VPN, everything works fine. Also the direct connections between the clients work. But neither Warcraft III nor Empire Earth is displaying any game hosted on the LAN. For Emprie Earth, I can bypass this with a direct connection to a 10.13.17.0/24 IP address in Warcraft III direct connections via Lancraft work like a charme.

I already found the related topics here on serverfault, with this one stating that you need bridging to get the UDP broadcasts to work.

From sniffing packages I know that Empire Earth sends a UDP package to 255.255.255.255 (broadcast) – these broadcasts also show up on another PC using Wireshark (both are using a different internet connection) – but I really don’t get why the games aren’t heeding these broadcasts. I might missing something obvious. Pings via the Windows cmd also work.

Here’s an example from the wireshark session:

Wireshark sesssion

Iptables udp rate limit a single ip

Hello I wanted to rate limit any udp traffic coming from 1.1.1.0/24
Can anyone suggest which rule shall I use?

I searched on google and got very big scripts. But didnt get any for rate limiting a ip/subnet with just 5 packets/sec

tor janus vm or vpn for tcp and udp traffic

I have a hyper-v server I want to use for malware analysis. I have setup a pfsense firewall routing internal vm traffic, out through pfsense wan port. I have set firewall rules so nothing on pfsense lan side can ping clients on pfsense wan side.

Now I have read I could use Janus VM to route traffic from pfsense wan side, out the Janus VM. The VM is a tor proxy. http://www.janusvm.com/tor_vm/

My concern is what if the malware uses udp or some weird port numbers to communicate. For example C2 traffic is SSH. Will Tor be good enough, or should I pay for a vpn service?

If I would use VPN it would be configured on pfsense side if possible for routing all traffic through vpn. Or a separate linux router, connected to VPN, routing all traffic from pfsense wan side, out to internet.

c# – Spoofing a UDP stream from a piece of software, to a third party app, in order to integrate with that app

I am working on a project where i am attempting to spoof a gps command from X-Plane 11 to allow a flight simulator that i am working on to communicate with an electroic flight bag app (Oz Runways)

The X-Plane software outputs a GPS stream that is sent to the app, which the app then interprets.
it is sent via UDP as an ascii Stream.

When the stream is sent, it shows the gps position of the plane in Xplane on a moving mapp in the App, on an Ipad.

An Example Stream: “XGPS1,-122.578640,47.264560,87.9936,8.2152,68.5358

At this stage i have tried taking the exact udp message (from Xplane, intercepted by Wireshark) and sending it from another program called Packet Sender. Sending the stream does not work, but sending the entire packet (which seems wrong) seems to give me the desired result.
The Entire Packet: “>ûÿÛEN©)À¨À¨ò¿i¿j:XGPS1,-122.578640,47.264560,87.9936,8.2152,68.5358

This makes the entire packet of this UDP message: “>ûÿÛEe®
À¨À¨ò¿i¿jQ«>ûÿÛEP{ÍÀ¨À¨ò¿i¿j<XGPS1,-122.307752,47.463464,124.7732,180.0498,0.0000

it seems like it doubles up on the leading data, like ip and port adresses etc.

So while this seems to work, when using my piece of software, which will change the numbers to send through the correct position and speed, but right now is just a simple c# udp sender it refuses to work.

    void openUDP()
    {
        udpClient = new UdpClient(49001);
        udpClient.Connect(IPAddress.Parse(textBoxip.Text), int.Parse(textBoxport.Text));
    }

    void DoUDPThings()
    {
        Byte() sendBytes = Encoding.UTF8.GetBytes(textBoxmsg.Text);
        try
        {
            udpClient.Send(sendBytes, sendBytes.Length);
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }

This is the code for my Sender, in order to mimic the Xplane software as much as possible i have set it to use the exact output port, and the text boxes in my win form feed in the message, ip address, and remote port number.

The actual question i suppose i am asking here, is why would copying the start of packet data work in Packet sender in the first place, and not in my c# program?

Below are two packets from wireshark one of which is from Xplane, the other is from my piece of software.

My software: 
183eef87a307001cbffbffdb08004500004ea95d000080110000c0a80006c0a800f2bf69bf6a003a829458475053312c2d3132322e3537383634302c34372e3236343536302c38372e393933362c382e323135322c36382e35333538

>ûÿÛEN©)À¨À¨ò¿i¿j:XGPS1,-122.578640,47.264560,87.9936,8.2152,68.5358
From Xplane: 
183eef87a307001cbffbffdb080045000050a94d000080110000c0a80006c0a800f2bf69bf6a003c829658475053312c2d3132322e3330323539322c34372e3436303236382c3133362e363139332c3236382e353936362c302e30373137

>ûÿÛEP©MÀ¨À¨ò¿i¿j<XGPS1,-122.302592,47.460268,136.6193,268.5966,0.0717

I understand that this is a very specific issue, but i simply do not understand why the same stream works from one piece of software and not another.