how can I prevent systemd-networkd from sending client identifier? - client

I have a machine with CoreOS 1800(or 1855) installed onto disk, and with following systemd-networkd config (there is only one network interface in the machine):
$ cat /etc/systemd/network/zz-default.network
[Network]
DHCP=yes
[DHCP]
ClientIdentifier=mac
UseMTU=true
UseDomains=true
Another notable thing is that this machine is also configured with PXE boot but PXE server will reject boot so it will finally boot from disk.
When I restart the machine, there will be two DHCP IPs allocated for it, I confirmed it by checking /var/lib/dhcpd.leases in DHCP server:
lease 100.79.223.152 {
starts 5 2018/09/28 02:34:00; ends 6 2018/09/29 02:33:59; tstp 6 2018/09/29 02:33:59; cltt 5 2018/09/28 02:34:00;
binding state active; next binding state free; rewind binding state free;
hardware ethernet 08:9e:01:d9:28:64;
option agent.circuit-id 0:5:8:b9:1:0:29;
}
lease 100.79.223.150 {
starts 5 2018/09/28 02:34:29; ends 6 2018/09/29 02:34:28; tstp 6 2018/09/29 02:34:28; cltt 5 2018/09/28 02:34:29;
binding state active; next binding state free; rewind binding state free;
hardware ethernet 08:9e:01:d9:28:64; uid "001010236001331(d";
option agent.circuit-id 0:5:8:b9:1:0:29;
}
The lease record 100.79.223.152 is requested by the PXE loader, though rejected by DHCP server.
The lease record 100.79.223.150 is requested by systemd-networkd of
CoreOS. (I can confirm it by running systemctl restart systemd-networkd and watch the leases file)
All seems fine, but the PXE lease record 100.79.223.152 cause other problem (when really PXE boot the machine and deploy another OS to it then it will get the 100.79.223.152 instead of 150, then cause other private problem).
If I install other OS which does not use systemd-networkd, then the reboot only cause 1 lease record.
You can see the lease 100.79.223.150 has a field uid "001010236001331(d", which means let DHCP server allocate IP by the uid (client identifier), currently it is actually same content of mac address, just be printed as octet.
This is the root cause of two IPs.
To prevent this two IP problem, I've tried to set deny duplicates in /etc/dhcp/dhcpd.conf in DHCP server, but nothing changes.
I was wandering that if it is possible to tell systemd-networkd not to send uid (client identifier). According to source of systemd, it is intentionally implemented to "always send client identifier",
given such condition, how can I prevent systemd-networkd from sending client identifier?
EDIT 2019/02/17: I found that I misunderstood the meaning of deny duplicates, it does not help this problem.
I remembered I had ever tested another option first but not works.
ignore-client-uids on;
The ignore-client-uids statement
ignore-client-uids flag;
If the ignore-client-uids statement is present and has a value of true
or on, the UID for clients will not be recorded. If this statement is
not present or has a value of false or off, then client UIDs will be
recorded.
https://www.isc.org/wp-content/uploads/2017/08/dhcp43.html
The DHCP server version is isc-dhcpd-4.2.4
EDIT 2019-03-12: I had some mistaken and found something, so answered this question myself. Simple answer is ignore-client-uids true; on server side works well, ClientIdentifier=mac on client side does not work well.

Have you tried setting the client identifier to (empty)?
$ cat /etc/systemd/network/zz-default.network
[Network]
DHCP=yes
[DHCP]
ClientIdentifier=
UseMTU=true
UseDomains=true

After many times of experiments, I found that only ignore-client-uids true; works constantly, all mystery disappeared., when you set it, you can confirm that no uid "....." appear in /var/lib/dhcp/dhcpd.leases` file, the server completely ignore the client identifier sent from client and just use MAC to determine how to allocate IP.
If you insist on using ClientIdentifier=mac, you can take a look at what I found:
specifying ClientIdentifier=mac (on client *.network) does let me get same IP as before. The reason why I said it does not work is probably because I have another NIC which also enabled DHCP by default hence caused a new IP.
/lib/systemd/network/zz-default.network
[Network]
DHCP=yes
[DHCP]
UseMTU=true
UseDomains=true
After I change above file to
[Network]
DHCP=no
I got only 1 and same IP as before.
The client identifier will be a string "\0x1" + MAC, you can confirm it grep uid "..." in /var/lib/dhcp/dhcpd.leasesfile, e.g.,uid "001304TDD210272"`, for any non-printable char it will be encoded as 3 digits Octal such as 304. Some client automatically generate an client identifier like this "\0x1" + "MAAS" + MAC ...
The most unfortunate thing is: once a client send client identifier, for the same MAC, if the client send anther request WITHOUT client identifier, it will get new IP.
Considering DDNS, for same MAC, the DHCP request with and without client identifier are treated as different client when DHCP server composing DNS update request for it. Simply speaking,
for DHCP request without client identifier -> server send DDNS request with a hash of the MAC -> DNS server: OK
for DHCP request with client identifier -> server send DDNS request with a hash of the client identifier -> DNS server: rejected due to the hash is not same, for security.
That is all I found, hope it helpful.

You can also check if there is configuration under the /run/.../systemd/network/*.network, I had the same issue because of netplan putting a configuration network file in the /run which is applied instead of the etc or lib one.
The solution in this case is to add the dhcp-identifier: mac in the the netplan yml configuration

Related

How to differentiate between closed and filtered remote ports

I am setting up port scanner for remote server in my application using Go. I am using DialTimeout function in Go net package to check whether a remote host port is opened or not. The result is fine with success case. But, if i/o timeout happens, I need to identify whether
The port is closed (No service is running) or
Port is blocked (Firewall filtered) or
Due to internet connectivity down in local system where the application is running.
Have tried nmap cli command, I can able to differentiate those failure 3 cases exactly.
nmap command tried: nmap -sA -p port_number host_ip
I found a Go 3rd party libray to use nmap.
But, I don't want to use nmap in my application. Are there any other alternatives in Go to exactly differentiate those 3 cases?
In the simple world
Lets assume you want to scan a Linux system.
If you get an ICMP message type 3 code 3, the firewall explicitly told you:
Hi, I am the firewall of your target host. The host is running. I hereby inform you that you (potentially amongst others) can not access this port. So now that you know you should quit your connection attempts. However, I won't tell you wether it is because there is no service running behind it (in which case my response is simply a courtesy) or because I was told to deny you access. Goodbye!
The port is closed if you do not get above answer and can not make a connection. I hence strongly advice to use context.WithTimeout to make a connection.
In the real world
However, this only applies if the admin of the target host did not change the ICMP message type to respond with - or chose just to drop any packets coming from sources which are not allowed to access the respective service. In the latter case, there is no way for you to know wether the port is closed or filtered.
All of the above only applies if we are talking of an iptables based firewall on the target system with default settings.
Now assume something which is by far more likely: A border firewall plus a local firewall. The border firewall might send other ICMP messages (or, again, simply drop your packages). Those rules apply additionally to the rules of the local firewall. So it is a misconception that you are actually scanning a host. It is more accurate to say that you scan the services reachable via a specific IP.
EDIT
Why would one send an ICMP message explicitly rejecting connection attempts?
There are various reasons to come to that decision. There is a good answer on serverfault.com

How to disable or enable option 97(pxe-client-id) in DHCP?

[Background]
As per below technical nodes, there is some improvement done in DHCP.
RHEL 6.7 Technical Notes
Enhancement
- BZ#1058674
With this update, the dhcpd daemon is able to handle dhcp option 97 - Client Machine Identifier (pxe-client-id),
so it is now possible to statically allocate an IP address for a particular client based on its identifier, sent in option 97.
example:
host pixi { option pxe-client-id 0 00:11:22:33:44:
[Problem]
In previous DHCP package (dhcp-4.1.1-43.P1) in RHEL6.6, we always received same IP address for adding new network interface with in existing network interface in case pxe calls through my Linux system reboot.
In RHEL 6.10, the DHCP package(dhcp-4.1.1-61.P1) always received different IP address for adding new network interface with in existing network interface.
It seems different IP is assigned due to this identifier. So, we are checking a options to disable sending of pxe-client-id in pxe client configuration.
[question]
Is there any way to disable or enable option 97(pxe-client-ID) in dhcp.
It seems same thing has been reported in RHEL7 link.
https://access.redhat.com/solutions/2158491

Microsoft Windows 7 PPP initialization sends "CLIENT" expects "SERVER" response

In Windows 7 I'm trying to set up a PPP connection over a direct serial port connection to a remote device. The documentation of the remote device (as well as the documentation I've found for the Windows PPP) indicates that the process should start with a Link Control Protocol packet, but I've discovered (by sniffing the serial line) that the PC, before doing anything else, is transmitting the string "CLIENT" once per second for up to 5 seconds. Only if the PC receives the response "SERVER" will it continue with the LCP initialization.
Does anyone know what level of system functionality is sending this CLIENT string, and how I can disable it. My remote device does not recognize this and refuses to connect based on this.
Update: I have discovered that this string is being initiated by the modem driver mdmhayes.inf as a "DialPrefix", but I have no idea how to update this driver file to eliminate this dial prefix. Thoughts?
Update: I've figured out how to get Windows to stop spitting out the "CLIENT" string (it has to do with changing the DIALPREFIX setting in the mdmhayes.inf file) but I still can't figure out how to make Windows realize it is connected and just move on with establishing the PPP connection. The modem diagnostics keep indicating that unknown strings are received so it doesn't know how to proceed. There should be some setting in the mdmhayes.inf file that tells the system not to wait for anything; it's connected to a wire and that's all that is needed. I just can't figure out what setting to use to make the modem initialization get out of the way to allow the PPP stack to take over.
in options.ttyS0 add:
debug
#19200
115200
192.168.111.1:192.168.111.2
netmask 255.255.255.0
lock
auth
nodefaultroute
nocrtscts
connect /etc/ppp/msclient.sh
msclient.sh :
#!/bin/sh
read -n 5 i
echo "SERVER"

Sending different requests to different servers based on protocal via dns

Is it possible to route dns to different servers based on the protocol of the request without using a proxy server?
For example wss://example.com goes to 1 server and https://example.com goes to a different one.
In principle no, this is not possible. Although there are exceptions.
When you an application and request a network address, e.g. example.com the application will (typically) pass on a request to the OS to open a connection to that address.
Because the OS can only make a connection to an IP Address, the first thing it does is to make a DNS request to find out the address it can connect to. There is no mechanism at all, to tell that DNS request what protocol is being requested. At the point the OS makes the DNS request it is simply, 'What is the address for example.com' there is no space in the body of the message for more information.
In that sense it is not possible.
However there are a few services that use SRV records to find the server they need to connect to.
In these cases the application will say to the OS 'get me the SRV record for _somefancyservice.example.com' When it has that record, it will then send another request to the OS to open a connection the whatever it found in the SRV record.
So you could, in theory, write an application that performed the SRV record query first, and then opened a connection to whatever was returned.
I wrote a more detailed answer specifically about wss, which you may find interesting.

Automatically send magic package on access

I configured my Windows 8 machine that it listens to magic packages send from other PCs to start it. It works very good. BUT I don't want to explicitly send a magic package, I would rather prefer it if I could send a magic package automatically when I try to access the PC over network.
I tryed using an smbclient event (30803). I configured this event to trigger a command line WOL. But This command will be triggered each time I get this event, no matter which PC I try to reach. I don't want to wake up PC-X when I actually try to access PC-Y.
Is there another way?
This sounds interesting... a possible solution would be, create a windows service and install it on the server or a computer that uses to be up. This service basically would be a network sniffer that captures all tcp traffic in network. It would have a table with ips and MAC addresses (to get MAC from an IP) that should be filled previously with manually or better... from ARP table (I did a program that gets IP / MAC from ARP table but has its issues... so each machine plugged on the LAN will get its MAC / IP), also this service would have last date ping done to each IP.
Then... how it would work... the service would capture all TCP packets and make a list of distinct IP, then each second or two get all distinct IPs (this will guarantee that the service is not consuming a lot of system resources), and on each distinct ip check last ping: if last ping was done successfully in last 5 or 10 minutes nothing is done (machine is guessed up), if no ping done or success in 5-10 minutes a ping is made. Based on ping response... if the machine is not responging magic packet is sent to MAC (provided from ARP when machine is up or manually as commented before). If ping responds nothing is done. Ping result and date is stored to avoid pings to all machines every time. Instead of ping also its possible to do it reading ARP table.
I this approach, system resources are preserved, and pings are made with sense, also magic packets are not sent if machine is up or guessed up.
Note that firewall should allow ICMP.

Resources