Network - From the NIC to the Internetz


How to make HTTPS and SSH share the TCP port 443 ?

Due to common corporate firewall rules, sshd is listening on TCP port 443 on your server. This is fine until you decide to enable TLS (i.e. HTTPS), because both SSH and your web server require access to the TCP port 443.

Here comes sslh, allowing to share the TCP port 443 between :

Setup procedure :

Free TCP 443 :

When beginning this procedure, the TCP port 443 is used by sshd. We must stop using this port, otherwise sslh won't be able to start.
  • SSH connections survive restarts of the daemon, and it's a good practice to keep an open connection as a backup, just in case you shoot your own leg (). But in this context, we have to completely stop using the port 443. This is why this operation comes with conditions :
    You must be able to open SSH connections towards a port which is not the 443. The port sshd is listening to (22 or anything you like) is not important as long as you can go through your corporate firewall / proxy. Don't go further if you can't do this !
  • As said above, as long as you can connect to sshd without using the TCP 443, whatever port you'll choose is fine. For this procedure, I'll use 22 and won't repeat 22 or any other port
Proceed :
  1. open an SSH session to TCP443. Keep this as a backup (make it active with ping/watch/top/... so that it won't timeout for inactivity)
  2. open another SSH session to TCP443. You'll use this one to make the changes below.
  3. edit /etc/ssh/sshd_config and change :
    Port 443
    into :
    Port 22
  4. restart sshd :
    systemctl restart sshd
  5. open a new SSH connection (now to port 22). If you specified the 443 port in ~/.ssh/config, you may have to temporarily comment / edit this setting.
  6. once you're successfully connected via 22, open an extra "backup connection" (and keep it active just as you did above)
  7. close the existing connections to 443
  8. make sure there is no process left listening on 443 :
    ss -punta | grep 443
Congratulations : TCP 443 is now FREE !!!

Setup SSLH (source, man page) :

  1. apt install sslh
  2. in /etc/default/sslh, change :
    into :
  3. and :
    DAEMON_OPTS="--user sslh --listen <change-me>:443 --ssh --ssl --pidfile /var/run/sslh/"
    into :
    DAEMON_OPTS="--user sslh --listen --ssh --ssl --pidfile /var/run/sslh/"
  4. enable and start it :
    systemctl enable sslh && systemctl start sslh
  5. check who's listening on TCP 443 :
    ss -punta | grep :443
    tcp	LISTEN	0	0	my.public.IP.address:443	*:*	users:(("sslh",pid=7330,fd=3),("sslh",pid=7328,fd=3))

Re-configure SSH accordingly :

Indeed, as configured in /etc/default/sslh, the SSH traffic is sent to
  1. Let's update /etc/ssh/sshd_config :
    Port 22
    This time, the port 22 is only involved in traffic that is internal to the server, so better sticking to the default value .
  2. open 1 SSH backup connection, just in case something goes wrong (this connection should go to the ssh daemon listening on
  3. restore the ~/.ssh/config configuration you changed earlier :
    • you're connecting anew to TCP 443, where SSLH is listening
    • SSLH forwards the traffic locally to SSH on TCP 22
  4. restart sshd :
    systemctl restart sshd
  5. check you can open a new SSH connection to your server (on port TCP 443, as specified in ~/.ssh/config)


If you have iptables rules to defeat brute-force attacks on sshd, it's time to update them :
  1. disable the existing rules (the way you'll do this depends on your setup : you _may_ not want to flush everything )
  2. create the new rules :
    iptables -I INPUT -p tcp -d --dport 22 -m state --state NEW -m recent --set
    iptables -I INPUT -p tcp -d --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 3 -j DROP
  3. test the new rules
  4. make them reboot-proof :
    systemctl enable netfilter-persistent.service && systemctl start netfilter-persistent.service
configure the webserver so that it listens on instead of

forward / reverse proxy

forward proxy

positioned at a network's edge, regulates outbound traffic according to preset policies in shared networks. Additionally, it disguises a client's IP address and blocks malicious incoming traffic
forward proxy

reverse proxy

intermediate connection point positioned at a network's edge. It receives initial HTTP connection requests, acting like the actual endpoint
reverse proxy

How to enable / disable reply to ping requests ?

As root :
echo 0 > /proc/sys/net/ipv4/icmp_echo_ignore_all
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all

You can check it locally with : ping


Network setup

  1. define the machine hostname (See also) :
    hostname foo
  2. assign IP addresses :
    number of hosts Address class Network Id Subnet Mask
    n < 255 class C from to
    255 < n < 65535 class B from to
    n > 65535 class A
  3. Loopback:
    • Check that the loopback is configured : /sbin/ifconfig
      The loopback IP should be
    • Otherwise type : ifconfig lo
    • Now, add it to the routing table : route add
    • Test it by pinging it : ping
  4. Ethernet interface :
    • same procedure : ifconfig eth0 netmask
    • route add -net
    • ping
    • route add -net
    • ping
  5. OR configure the network interface :

    for Debianoids :

    in /etc/network/interfaces (sources 1, 2) :
    • loopback interface :
      # The loopback network interface
      auto lo
      iface lo inet loopback
    • ethernet interface, static configuration :
      # The primary network interface
      auto eth0
      allow-hotplug eth0
      iface eth0 inet static
    • ethernet interface, DHCP configuration :
      # The primary network interface
      auto eth0
      allow-hotplug eth0
      iface eth0 inet dhcp
    • wireless interface with WEP and DHCP (More information on WiFi configuration) :
      auto wlan0
      iface wlan0 inet dhcp
      	wireless-essid myEssid
      	wireless-key myWepKey
    The auto keyword specifies that the corresponding interface will be put "up" :
    • at boot time
    • if ifup is invoked with the -a flag.
    The allow-hotplug keyword specifies that the corresponding interface can be brought up automatically by the hotplug subsystem.

    Don't forget to restart the networking management : /etc/init.d/networking restart

    for Red Hatoids :

    in /etc/sysconfig/network-scripts/ifcfg-ifname :
    Not reboot-proof ?
    Make sure the /ifcfg-ifname file has :
  6. the /etc/hosts file should look like :	localhost	foo
  7. Test it :
    • ping localhost
    • ping foo
  8. DNS servers are configured in /etc/resolv.conf

How to detect whether the current shell is running locally or through SSH ?

When bash is run through an SSH session :

host address, subnet mask, subnet address and broadcast address

Let's consider the IP address. What does this mean ?

Other example :, let's find the subnet and broadcast addresses

                    binary                                  decimal
host address        aaaaaaaa.bbbbbbbb.cccccccc.00101000
subnet mask         11111111.11111111.11111111.11100000
                    |<----------27 bits--------->|

subnet address      aaaaaaaa.bbbbbbbb.cccccccc.00100000		host address AND subnet mask
broadcast address   aaaaaaaa.bbbbbbbb.cccccccc.00111111		subnet address with host bits set to 1

The TCP protocol

Connection establishment (source) :

The TCP three-way handshake
TCP three-way handshake

Connection termination (source)

TCP connection termination
TCP connection termination

Connection states (source, RFC 793) :

CLOSE_WAIT (sources : 1, 2)

CLOSE_WAIT means that the local end of the connection has received a FIN from the other end, but the OS is waiting for the program at the local end to actually close its connection.

Having plenty of CLOSE_WAIT is caused by a program running on the local machine not closing the socket. It is not a TCP tuning issue. A connection can (and quite correctly) stay in CLOSE_WAIT forever while the program holds the connection open. It's the responsibility of an application (i.e. not to the OS) to close its socket once the remote computer closes its side of the TCP communication.

Once the local program closes the socket, the OS can send the FIN to the remote end which transitions you to LAST_ACK while you wait for the ACK of the FIN. Once that is received, the connection is finished and drops from the connection table.

If you are seeing a large number of connections persisting in CLOSE_WAIT state it's probably a problem with the app itself : connections have been torn down but your side of things still has a file descriptor open.
Solutions :

  • restart the application : it will clear the connections temporarily but obviously the same problem will occur later on.
  • kill processes in CLOSE_WAIT state : will get you rid of those connections, but it can be dangerous because these processes still have right to send remaining data in queue
  • fix your software

When an application connection is closed between a server and its client, TCP maintains the connection for a little while before effectively closing it. "Closing" a connection actually means releasing a pair of connection sockets, that are instantly available for new connections. Keeping the connection "alive" for some extra seconds is just in case some packets were lost / late and prevent them from :
  • reaching a newly established connection with the same as before sockets numbers
  • OR being replied with a RST signal (source)

Other features :

keepalive (details in RFC 1122)
Periodically probes the other end of a connection when the connection is idle, even when there is no data to be sent.
Used in server applications that might otherwise hang indefinitely and consume resources unnecessarily if a client crashes or aborts a connection during a network failure.

Bridge network connection

Bridging a network connection is a handy method for sharing a network internet connection between two computers. A bridge is a virtual interface that just takes the packets from one interface, and transparently (i.e. without altering outgoing or incoming frames) routes them to another.

You can list existing interfaces with ip link.

Prerequisite : aptitude install bridge-utils will provide you with the brctl command.

"Manual" configuration of a bridge :

  1. enumerate the existing devices to identify those to be bridged : ip addr show
  2. bring down the interfaces to bridge : ifdown eth0; ifdown eth1
  3. create the bridge interface : brctl addbr br0 (br0 is just an example, you can name the bridge interface as you like)
  4. "connect" the eth0 and eth1 interfaces to the br0 bridge : brctl addif br0 eth0 eth1
  5. bring the br0 interface up, and voilà! This is the only interface that will get an IP address (?)

Configuring bridging in /etc/network/interfaces with DHCP :

  1. Edit /etc/network/interfaces so that it looks like :
    • For general purpose :
      # The loopback network interface
      auto lo br0
      iface lo inet loopback
      # Set up interfaces manually, avoiding conflicts with, e.g., network manager
      iface eth0 inet manual
      iface eth1 inet manual
      # Bridge setup
      iface br0 inet dhcp
      	bridge_ports eth0 eth1
    • For virtualized environments :
      # The loopback network interface
      auto lo br0
      iface lo inet loopback
      # Set up interfaces manually, avoiding conflicts with, e.g., network manager
      iface eth0 inet manual
      iface eth1 inet manual
      # Bridge setup
      iface br0 inet dhcp
      	bridge_stp	off		# disable Spanning Tree Protocol
      	bridge_waitport	0		# no delay before a port becomes available
      	bridge_fd	0		# no forwarding delay
      	bridge_ports	none		# if you do not want to bind to any ports
      	bridge_ports	regex eth*	# use a regular expression to define ports
  2. To enable the bridge : ifup br0

bridge management commands (source) :

  • list devices in a bridge : brctl show br0
  • remove an interface from a bridge : brctl delif br0 eth0
  • shutdown a bridge : brctl delbr br0

How to handle Internationalized Domain Names ?

When working with a domain name containing non-ASCII characters, you need to convert the domain name into punycode before entering it into the DNS server.
idn2 www.télé
Returns :
idn2 ąćęłńóśźż.pl
Returns :
nslookup $(idn2 ąćęłńóśźż.pl)
Returns :
Non-authoritative answer:
ping -c1 $(idn2 ąćęłńóśźż.pl)
Returns :
PING ( 56(84) bytes of data.
64 bytes from ( icmp_req=1 ttl=43 time=122 ms

--- ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 122.774/122.774/122.774/0.000 ms

Share files with Python and a HTTP server

How do you do this ? (source)

  1. on the host having the files to share (aka theServer), cd to the directory containing those files
  2. share files :
    • with Python 2 : python -m SimpleHTTPServer port
    • with Python 3 : python -m http.server port
  3. On the client side, files will be available at http://theServer:port. You can retrieve files easily with wget -c url

Is it efficient, at least ? Let's check this !

Let's start by generating some test data :

dd if=/dev/urandom of=/tmp/testFile bs=1M count=500 & watch -n 1 -d 'ls -lh /tmp/testFile'

Don't try this with /dev/random or it will take forever.

The Python method :

Get the server's IP address :
hostname -i
Serve the file :
cd /tmp; python -m SimpleHTTPServer 8888
Get the file from another host :
cd /tmp; time wget -O ./testFile
-O ./testFile is there so that we can repeat the download without creating ./testFile.1, ./testFile.2, ...
Length: 524288000 (500M) [application/octet-stream]
Saving to: `./testFile'

100%[============================================================================>] 524,288,000 90.8M/s in 5.2s

2015-06-12 11:55:00 (96.7 MB/s) - `./testFile' saved [524288000/524288000]

real	0m5.289s
user	0m0.137s
sys	0m1.950s

The scp method :

Get the file from another host :
time scp root@ /tmp/testFile
testFile								100%	500MB	33.3MB/s	00:15

real	0m14.233s
user	0m11.118s
sys	0m4.453s

The Rsync method :

Get the file from another host :
[ -f "/tmp/testFile" ] && rm -f /tmp/testFile; time rsync -avz -e ssh root@ /tmp/testFile
receiving incremental file list

sent 30 bytes	received 524543976 bytes	13987840.16 bytes/sec
total size is 524288000	speedup is 1.00

real	0m37.000s
user	0m13.829s
sys	0m3.601s

Results :

  • From fastest to slowest : Python, scp, Rsync.
  • Files sent via the Python method will transit in clear format (no encryption), which should be avoided outside of a controlled environment such as a LAN.
  • If the shared file contains "incremental" data (such as a database dump, a logfile, ..., meaning most of the data has already been transmitted), Rsync is able to transfer only the updated chunks and may be the optimal solution.

Network parameters

On Debianoids On Red Hatoids On both
Where are they stored ?
Network Manager ignores these files (details).
  • global : /etc/sysconfig/network
  • interface-specific : /etc/sysconfig/network-scripts/ifcfg-ifname
  • VPN, mobile broadband, PPPoE : /etc/NetworkManager/system-connections/
source, network setup
DNS resolution is configured in /etc/resolv.conf
To load changes : systemctl restart networking systemctl restart network
How to change the hostname ?
  • old (source) :
    echo newHostname > /etc/hostname && /etc/init.d/
  • in Debian Buster (10) (source) and Ubuntu 18.04 (source) :
    1. hostnamectl set-hostname newHostname
    2. update the corresponding entry in /etc/hosts
  • up to RHEL 6 :
    • temporary : hostname newHostname
    • reboot-proof (source) :
      1. sed -ri 's/^HOSTNAME=.*$/HOSTNAME=newHostname/' /etc/sysconfig/network
      2. check :
        grep -E '^HOSTNAME' /etc/sysconfig/network
      3. make sure /etc/hosts has a line such as : newHostname
      4. reboot
  • since RHEL 7 (source) :
    hostnamectl set-hostname newHostname
  • Check it with :

Proxy settings :

If you landed here while having questions about proxy settings and Git, you may find answers there.

Proxy settings are saved in /etc/profile or /etc/environment (system-wide settings) or in ~/.bashrc (personal settings including proxy credentials) :

export http_proxy="http://proxyUser:proxyPassword@proxyHost:proxyPort/"
export https_proxy=$http_proxy
export ftp_proxy=$http_proxy

After editing one of these files, reload it : source theFileIJustEdited

All fields (and especially the password) must be url-encoded.




  • ARP is used to convert IP addresses (or hostnames) into MAC addresses. It's implemented in all the operating systems that are able to connect to a network.
  • RARP is reverse-ARP and converts MAC addresses into IP addresses. It's seldom implemented in operating systems since once any host is reachable through ping, a basic arp -a | grep any_MAC_address may output the answer.


Function Windows command Linux command FreeBSD command Details
get the MAC address matching a known IP address arp -a arp IP_address
display the whole content of the ARP table arp -a arp -a
flush the whole content of the ARP table arp -d (not possible ?) arp -a -d
flush one host from the ARP table arp -d IP_address
set a static record in the ARP table arp -s IP_address MAC_address On Windows, the MAC address is in the format xx-xx-xx-xx-xx-xx

How to retrieve the MAC address of a distant host ?

ip neigh show | grep ''


Let's play with hping


hping (get it : from home site) is a packet builder that can be used to :

Here's an example hping command line :

hping -S -p ++1 target --fast | grep "SA"


Parameter Usage Details / Example
-a IP_address spoof IP_address tell the target host that packet are from IP_address
-A toggle the ACK flag
-c n count : send n packets
-d n send n bytes of data
  • n must be <= 65535
  • The highest value (due to headers) is 65495 (this makes the network of an XP host 5% busy)
  • In --fast mode, the biggest payload makes the network of an XP host 5% busy
  • In --faster and --flood modes, the biggest payload makes the network of an XP host 97% busy, and the CPU more than 50% busy
-F toggle the FIN flag
-k keep source port This is to be used with the -s option to prevent hping from incrementing the source port.
-p x set x as destination port
-p 80
reaches an HTTP server
-p +n
destination port is increased after each reply received
-p ++n
destination port is increased after each packet sent
-R toggle the RST flag
-s x set x as source port By default, hping uses a random port as its source port and increases it after each packet sent. This can be overridden with the -s and -k options.
-S toggle the SYN flag


Goal Details Command line
Ensure a given TCP port is open Let's send a SYN packet to the HTTP port of the host target (1 packet is enough). Based on the TCP three-way handshake, an open port will reply with a SA-flagged packet. hping -S -p 80 c200 -c 1
Ensure a Windows host is up On many Windows hosts, some ports (Netbios - 139, portmapper - 135, among many others) are often left open. Any reply shows the host is up.
SA shows the connection is allowed.
RA shows the connection is refused.
This technique isn't 100% reliable. If the target port is firewalled with a DROP rule, there'll be no answser.
hping -S -p 135 c200 -c 1

Altering ARP tables with arp-sk (aka ARP spoofing or ARP poisoning)

Prerequisites - a little bit of theory

Before going further, make sure you understand the basics of ARP. If you want to know more, just have a look at the RFC 826. also seems to be a good starting point.
Our target is to play the MitM, capture some traffic and understand why switched environments security is a fairy tale. You should read first this presentation on ARP attacks with arp-sk (french version).
This means we're about to alter the ARP table of a distant host (target) with fake IP-MAC value pairs to let target believe it's connected to resource whereas it's actually connected to sniff. But since packets are expected back from resource to target, we also have to let resource believe it's connected to target, whereas it's actually connected to sniff.

To do so, we'll have to :

  • route packets going through sniff
  • perform double simultaneous ARP cache poisoning

Structure of a normal ARP "who has" request :

Format of ARP requests :
Who has target_IP ? Tell sender_IP
The ARP packet itself contains (among other things) :
Ethernet Frame (or "Link Layer") arp-sk option
SRC MAC MAC address of host sending the request -s (can be used to specify either MAC / IP / host)
SRC IP / host (not used)
DST MAC broadcast : ff:ff:ff:ff:ff:ff -d (can be used to specify either MAC / IP / host)
DST IP / host (not used)
ARP message arp-sk option
Sender MAC MAC address of host sending the request -S :MACxx:xx:xx:xx:xx:xx
Sender IP IP address of host sending the request -Sxxx:xxx:xxx:xxx
Target MAC 00:00:00:00:00:00 -D :MACxx:xx:xx:xx:xx:xx
Target IP IP address of host receiving the request -D xxx:xxx:xxx:xxx
  • The ARP protocol doesn't specify there MUST be consistency between the Ethernet frame data and the ARP message content itself.
  • Dynamic ARP cache entries expire after 2 minutes when unused. Otherwise, used entries are automatically renewed every 10 minutes (details 1, details 2).
  • Some operating systems like Solaris do not accept ARP replies without first initiating an ARP request, so they are not vulnerable to this attack. In this case, an ICMP spoofed packet (ping) is used. The goal is to get a valid entry in target's ARP cache, because when they receive an ARP reply from you they will first check their cache to see if you're already there and if you're not, they simply won't add you at all.

Download arp-sk :

Playing with arp-sk :

arp-sk -w -d host -s MAC -S IP -c 1

  • -w means we're sending a fake ARP "who has ... ?" query
  • host is the hostname / IP of the machine which ARP cache is going to be modified
  • MAC is the MAC address to insert into host's ARP cache
  • IP is the IP address matching MAC in host's ARP cache
  • -c n : send n packets. If omitted, packets will be sent continuously (which is a good thing anyway since ARP cache could be refreshed with "good" values, which is not what we want.)
  • -T n : wait n seconds (or un microseconds) between sending each packet. You can also use --rand-time n to randomize the sending period between -n and +n.

To perform a DoS :

  • host is the IP / hostname of the station you want to disconnect
  • MAC is fake (01:23:45:67:89:0a works fine but looks too obvious. Have a look at the --rand-arp option)
  • IP is the IP / hostname of the resource host will be disconnected from

To perform a MitM attack :

  1. enable packet routing on sniff
  2. As sniff, make target believe you're resource : arp-sk -w -d IP_t -s MAC_sniff -S IP_r
  3. As sniff, make resource believe you're target : arp-sk -w -d IP_r -s MAC_sniff -S IP_t

Answers to IP packets

When sending ... to remote host Reply should be ...
TCP SYN (to open port) TCP SYN/ACK
TCP SYN (to closed port) TCP RST (ACK)
TCP RST no response
ICMP Echo_Request ICMP Echo_Reply
ICMP TS_Request ICMP TS_Reply
UDP pkt (to open port) protocol dependent
UPD pkt (to closed port) ICMP Port Unreachable

Routes and route

The GNU/Linux command route is now obsolete. Use ip route instead.

Basics / rules / "en vrac"

  • the gateway must be on the same network than the current network interface.
  • the default gateway should be the one through which go the greatest number of routes instead of the network traffic.

Details : let's communicate from x.x.0.1 to x.x.1.1

As seen by host A : is host B on my subnet ?
  • yes
    1. host A sends an ARP request to get host B's MAC address
    2. host A sends data to host B
  • no
    1. host A chooses a route based on destination
    2. host A sends an ARP request to get GW's MAC address of x.x.0.254 interface
    3. host A sends data to GW. The IP headers will look like :
      SRC DST
      IP x.x.0.1 x.x.1.1
      MAC MAC of x.x.0.1 MAC of GW x.x.0.254
    4. GW passes data from the x.x.0.254 interface to the x.x.1.254 interface
    5. GW asks whether x.x.1.254 is on its subnet (as seen from its x.x.1.254 interface) ?
      1. no : same process to route again
      2. yes
        1. GW sends an ARP request to get host B's MAC address
        2. GW sends data to host B. The IP headers will look like :
          SRC DST
          IP x.x.0.1 x.x.1.1
          MAC MAC of x.x.1.254 MAC of GW x.x.1.1


Configure Evergreen as the router :

  • On Evergreen (SuSE 9.0), I have to declare :
    route add -net netmask gw eth0
    route add -net netmask gw eth1
    so that the kernel knows where to send packets.
  • On P600 (XP Pro), I just have to define as the default gateway.

Configure Atlantis as the router to Internet :

  • On Atlantis (Mandrake 9.2), the appropriate routes are defined while setting up the Internet connection
  • On Evergreen (SuSE 9.0), I just have to declare that Atlantis is the default gateway to the Internet. To do so:

    route add default gw eth1

    • route add : usual command to add a route towards a new host or a new network.
    • default : it's an alias for -net netmask It means all the networks, whatever netmask they have, which matches with Internet. It's also to specify to apply this route whenever none of the others routes match.
    • gw : for gateway. Just a keyword of the route command.
    • : This is the address where Evergreen's packets should be sent in order to reach Internet. This is Atlantis'IP address.
    • eth1 : the interface through which the packets must be sent to

Allow Linux to route packets :

echo 1 > /proc/sys/net/ipv4/ip_forward

Running this on the router side will overwrite the existing /proc/sys/net/ipv4/ip_forward file and simply write a 1 inside.

Create a new route to a network :

  • Linux : route add -net networkAddress netmask netmask gw gatewayToTargetNetwork ethX
  • W2K : route add networkAddress mask netmask gatewayToTargetNetwork

Delete an existing route :

route del -net networkAddress netmask netmask

The OSI model

OSI model OSI model

How to spoof a MAC address ?

Make a temporary change (not reboot-proof) :

ifconfig wlan1 down hw ether 00:15:AF:99:3E:27 && ifup wlan1

As this is a software hack, the real MAC address will be restored the next time the interface will be "re-discovered" by the kernel : reboot or reload of the kernel module.

Alter it permanently (source) :

  1. Edit /etc/network/interfaces
  2. Find the section matching the interface you want to edit. Should look like :
    allow-hotplug eth0
    iface eth0 inet dhcp
  3. Append a new line with the new MAC address :
    allow-hotplug eth0
    iface eth0 inet dhcp
    	hwaddress ether B0:0B:50:00:00:02
  4. Restart the network, and check the new settings : service networking restart; service networking restart; ip link show eth0
    I don't know why so far, but it doesn't work unless you restart the network twice...
    2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
    link/ether b0:0b:50:00:00:02 brd ff:ff:ff:ff:ff:ff

And it also survives a reboot


How to obtain / renew / release an IP address with DHCP ?

Obtaining or renewing the IP address

There are several methods :
  • dhclient eth0
  • ifdown eth0 && ifup eth0
  • /etc/init.d/networking restart

Releasing without renewing the IP address

dhclient -r wlan0

dhclient files

  • configuration : /etc/dhcp3/dhclient.conf
  • leases :
    • for all interfaces : /var/lib/dhcp3/dhclient.leases
    • for each interface : /var/lib/dhcp3/dhclient.wlan0.leases

How to make sure a distant daemon is listening / probe for an open port / test network connectivity ?

This article lists / links several techniques to say knock knock ? on the line. Be careful when interpreting the answers you get :
  • Things like Who's there? and Please come in, it's warm inside! mean everything is going extremely well
  • Go f*ck yourself!!! is an interesting answer since it means you've been able to talk to someone (even though they won't let you in)
  • No answer at all can have several causes :
    • either nobody's listening at the other end of the line (is the daemon started ? Have you dialed the right port number ?)
    • OR you can't speak to them because of someone in the middle (a firewall, a proxy, ...)

Use :

Alternate solution

It's pretty likely that utilities listed above are not available, but there are still some hacks to try

With Python

Test the socket (source) :

  1. start a Python shell : python3
  2. run :
    import socket
    s.connect(('', 8888))
  3. If this returns ...
    • nothing : it means opening the socket succeeded
    • things like :
      • ConnectionRefusedError: [Errno 111] Connection refused
      • socket.error: [Errno 113] No route to host
    • Now, you know

Send an HTTP request (source) :

  1. Run:
    import http
    conn = http.client.HTTPConnection('')
    conn.request('GET', '/')
    response = conn.getresponse().read()
  2. If you get :
    • >>> conn.request()
      	Traceback (most recent call last):
      	ConnectionRefusedError: [Errno 111] Connection refused
      That sounds clear enough
    • HTML data —either the page you requested or an error response page (most likely saying 404)— you've successfully communicated with the web server

import socket

UDP_IP = ""
UDP_PORT = 123
MESSAGE = "hello world"

print("UDP target IP: %s" % UDP_IP)
print("UDP target port: %s" % UDP_PORT)
print("message: %s" % MESSAGE)

sock = socket.socket(socket.AF_INET, # Internet
                     socket.SOCK_DGRAM) # UDP
sock.sendto(MESSAGE.encode(), (UDP_IP, UDP_PORT))

With Bash and pseudo-devices

Test the socket (source)

  • Connection successful :
    I do have something on localhost listening on port 8888.
    address=''; port='8888'; timeout 1 bash -c "< /dev/tcp/$address/$port"; echo $?
  • Connection failure prior to the timeout :
    address="$(pwgen -N 1 12).com"; port='80'; timeout 1 bash -c "< /dev/tcp/$address/$port"; echo $?
    the pwgen thing is to generate a random host name
    bash: line 1: Name or service not known
    bash: line 1: /dev/tcp/ Invalid argument
  • Connection not established, killed by timeout :
    address=""; port='81'; timeout 1 bash -c "< /dev/tcp/$address/$port"; echo $?

Send an HTTP request (source, details about redirections and file descriptors) :

There is an HTTP server on localhost listening on port 8888.
  1. address=''; port='8888'; exec 3<>"/dev/tcp/$address/$port"; echo -e 'GET / HTTP/1.1\r\n' >&3; cat <&3
    What this command does :
    1. exec 3<>"/dev/tcp/$address/$port"
      open /dev/tcp/$address/$port as file descriptor 3 for both reading and writing
    2. echo -e 'GET / HTTP/1.1\r\n' >&3
      the output of echo (implicit file descriptor 1) is made a copy of file descriptor 3, which redirects the output of echo : writing to /dev/tcp/$address/$port
    3. cat <&3
      the input of cat (implicit file descriptor 0) is made a copy of file descriptor 3, which redirects the input of cat : reading from /dev/tcp/$address/$port
  2. As above, you'll get either
    • an error stating you can't connect to the HTTP server
    • OR some HTML data : the page you requested / an HTTP 404 error page