I want to clear the arp cache in Linux, and I have tried to do it with
IP -s -s neigh flush all And also with arp -d <specific IP address>
Both of them does not work...
Check where is your arp binary located:
$ which arp
/usr/sbin/arp
The sbin proposes that the binary is intended to be run by superuser. IT touches things that you don't want to give normal users to touch, as described in manual page:
arp -d address
will delete a ARP table entry. Root or netadmin priveledge is required to do this. The entry is found by IP address. If a hostname is given, it will be resolved before looking up the entry in the ARP table.
You need to run it as a root, for example using sudo should work for you:
sudo arp -d <specific IP address>
Related
Now I am connecting to endpoint using this command:
ssh my.jumphost.com -t 'export iip=111.22.3.44; bash'
The problem is that I don't have direct access to this IP, I mean I can't just ssh 111.22.3.44 from my jumphost. So basically I can reach destination host only if I export this variable with IP address from jumphost.
I've already looked into scp command and the way with ssh tunnel, but seems like both of them are required direct access to destination host.
I've also tried
cat test.py | ssh my.jumphost.com -t 'export iip=111.22.3.44' 'cat > /home/user/test.py'
but in that case file is being copied to jumphost only.
Any advice or guidance would be greatly appreciated!
How does ip netns exec command create a mount namespace and prevent the changes from being propagated to other mount namespaces?
Following is the from the man page of ip-netns:
For applications that are aware of network namespaces, the convention
is to look for global network configuration files first in
/etc/netns/NAME/ then in /etc/. For example, if you want a different
version of /etc/resolv.conf for a network namespace used to isolate
your vpn you would name it /etc/netns/myvpn/resolv.conf.
ip netns exec automates handling of this configuration, file
convention for network namespace unaware applications, by creating a
mount namespace and bind mounting all of the per network namespace
configure files into their traditional location in /etc.
But, how does it manage the bind mount being visible only in that particular namespace?
Let me show an example.
In one terminal, I create a network namespace ns3, and create a specific resolv.conf for ns3.
# ip netns add ns3
# mkdir /etc/netns/ns3
# echo "ns3 conf" > /etc/netns/ns3/resolv.conf
# ip netns exec ns3 sleep 36000
Now in another terminal, I examine the /etc/resolv.conf.
# cat /etc/resolv.conf
default conf
The change made by the bind mount is not reflected here.
The change is visible, only if i enter the mount namespace created by the ip netns command.
# lsns | grep mnt
4026533472 mnt 1 13016 root sleep 36000
# nsenter -m -t 13016
# cat /etc/resolv.conf
ns3 conf
So all works as expected.
Now let me try to do this directly with unshare command, instead of using ip netns exec.
I create a namespace again. With unshare, I am creating a mount namespace and doing the bind mount inside that mount namespace. I assume this is what ip netns exec command internally does.
# ip netns add ns4
# mkdir /etc/netns/ns4
# echo "ns4 conf" > /etc/netns/ns4/resolv.conf
# unshare -m --propagation unchanged /bin/bash
# mount --bind /etc/netns/ns4/resolv.conf /etc/resolv.conf
But this time when I check from another terminal, the changes have been propagated back which is not desired.
# cat /etc/resolv.conf
ns4 conf
So what is the additional step that ip netns exec does which prevent this propagation of changes? I assume it is related to the usage make-shared or make-slave flags, but couldn't figure out exactly.
Found out that if I use # unshare -m --propagation slave /bin/bash, the propagation is prevented.
ip netns exec command seems to be running mount --make-rslave / after unshare(CLONE_NEWNS) is done.
i.e, after new mount namespace is created, / is mounted as slave in that namespace.
I'm perfectly happy with the IP range that docker is giving me by default 176.17.x.x, so I don't need to create a new bridge, I just want to give my containers a static address within that range so I can point client browsers to it directly.
I tried using
RUN echo "auto eth0" >> /etc/network/interfaces
RUN echo "iface eth0 inet static" >> /etc/network/interfaces
RUN echo "address 176.17.0.250" >> /etc/network/interfaces
RUN echo "netmask 255.255.0.0" >> /etc/network/interfaces
RUN ifdown eth0
RUN ifup eth0
from a Dockerfile, and it properly populated the interfaces file, but the interface itself didn't change. In fact, running ifup eth0 within the container gets this error:
RTNETLINK answers: Operation not permitted Failed to bring up eth0
I have already answered this here
https://stackoverflow.com/a/35359185/4094678
but I see now that this question is actually older then the aforementioned one, so I'll copy the answer as well:
Easy with Docker version 1.10.1, build 9e83765.
First you need to create you own docker network (mynet123)
docker network create --subnet=172.18.0.0/16 mynet123
than simply run the image (I'll take ubuntu as example)
docker run --net mynet123 --ip 172.18.0.22 -it ubuntu bash
then in ubuntu shell
ip addr
Additionally you could use
--hostname to specify a hostname
--add-host to add more entries to /etc/hosts
Docs (and why you need to create a network) at https://docs.docker.com/engine/reference/commandline/network_create/
I'm using the method written here from the official Docker documentation and I have confirmed it works:
# At one shell, start a container and
# leave its shell idle and running
$ sudo docker run -i -t --rm --net=none base /bin/bash
root#63f36fc01b5f:/#
# At another shell, learn the container process ID
# and create its namespace entry in /var/run/netns/
# for the "ip netns" command we will be using below
$ sudo docker inspect -f '{{.State.Pid}}' 63f36fc01b5f
2778
$ pid=2778
$ sudo mkdir -p /var/run/netns
$ sudo ln -s /proc/$pid/ns/net /var/run/netns/$pid
# Check the bridge's IP address and netmask
$ ip addr show docker0
21: docker0: ...
inet 172.17.42.1/16 scope global docker0
...
# Create a pair of "peer" interfaces A and B,
# bind the A end to the bridge, and bring it up
$ sudo ip link add A type veth peer name B
$ sudo brctl addif docker0 A
$ sudo ip link set A up
# Place B inside the container's network namespace,
# rename to eth0, and activate it with a free IP
$ sudo ip link set B netns $pid
$ sudo ip netns exec $pid ip link set dev B name eth0
$ sudo ip netns exec $pid ip link set eth0 up
$ sudo ip netns exec $pid ip addr add 172.17.42.99/16 dev eth0
$ sudo ip netns exec $pid ip route add default via 172.17.42.1
Using this approach I run my containers always with net=none and set IP addresses with an external script.
Actually, despite my initial failure, #MarkO'Connor's answer was correct. I created a new interface (docker0) in my host /etc/network/interfaces file, ran sudo ifup docker0 on the host, and then ran
docker run --net=host -i -t ...
which picked up the static IP and assigned it to docker0 in the container.
Thanks!
This worked for me:
docker run --cap-add=NET_ADMIN -d -it myimages/image1 /bin/sh -c "/sbin/ip addr add 172.17.0.8 dev eth0; bash"
Explained:
--cap-add=NET_ADMIN have rights for administering the net (i.e. for the /sbin/ip command)
myimages/image1 image for the container
/bin/sh -c "/sbin/ip addr add 172.17.0.8 dev eth0 ; bash"
Inside the container run ip addr add 172.17.0.8 dev eth0 to add a new ip address 172.17.0.8 to this container (caution: do use a free ip address now and in the future). Then run bash, just to not have the container automatically stopped.
Bonus:
My target scene: setup a distributed app with containers playing different roles in the dist-app. A "conductor container" is able to run docker commands by itself (inside) so to start and stop containers as needed.
Each container is configured to know where to connect to access a particular role/container in the dist-app (so the set of ip's for each role must be known by each partner).
To do this:
"conductor container"
image created with this Dockerfile
FROM pin3da/docker-zeromq-node
MAINTAINER Foobar
# install docker software
RUN apt-get -yqq update && apt-get -yqq install docker.io
# export /var/run/docker.sock so we can connect it in the host
VOLUME /var/run/docker.sock
image build command:
docker build --tag=myimages/conductor --file=Dockerfile .
container run command:
docker run -v /var/run/docker.sock:/var/run/docker.sock --name=conductor1 -d -it myimages/conductor bash
Run containers with different roles.
First (not absolutely necessary) add entries to /etc/hosts to locate partners by ip or name (option --add-host)
Second (obviously required) assign a ip to the running container (use
/sbin/ip in it)
docker run --cap-add=NET_ADMIN --add-host worker1:172.17.0.8 --add-host worker2:172.17.0.9 --name=worker1 -h worker1.example.com -d -it myimages/image1 /bin/sh -c "/sbin/ip addr add 172.17.0.8 dev eth0; bash"
Docker containers by default do not have sufficient privileges to manipulate the network stack. You can try adding --cap-add=NET_ADMIN to the run command to allow this specific capability. Or you can try --privileged=true (grants all rights) for testing.
Another option is to use pipework from the host.
Setup your own bridge (e.g br0)
Start docker with: -b=br0
& with pipework (192.168.1.1 below being the default gateway ip address):
pipework br0 container-name 192.168.1.10/24#192.168.1.1
Edit: do not start with --net=none : this closes container ports.
See further notes
I understood that you are not looking at multi-host networking of containers at this stage, but I believe you are likely to need it soon. Weave would allow you to first define multiple container networks on one host, and then potentially move some containers to another host without loosing the static IP you have assigned to it.
pipework also great, but If you can use hostname other than ip then you can try this script
#!/bin/bash
# This function will list all ip of running containers
function listip {
for vm in `docker ps|tail -n +2|awk '{print $NF}'`;
do
ip=`docker inspect --format '{{ .NetworkSettings.IPAddress }}' $vm`;
echo "$ip $vm";
done
}
# This function will copy hosts file to all running container /etc/hosts
function updateip {
for vm in `docker ps|tail -n +2|awk '{print $NF}'`;
do
echo "copy hosts file to $vm";
docker exec -i $vm sh -c 'cat > /etc/hosts' < /tmp/hosts
done
}
listip > /tmp/hosts
updateip
You just need to run this command everytime you boot up your docker labs
You can find my scripts with additional function here dockerip
For completeness: there's another method suggested on the Docker forums. (Edit: and mentioned in passing by the answer from Андрей Сердюк).
Add the static IP address on the host system, then publish ports to that ip, e.g. docker run -p 192.0.2.1:80:80 -d mywebserver.
Of course that syntax won't work for IPv6 and the documentation doesn't mention that...
It sounds wrong to me: the usual wildcard binds (*:80) on the host theoretically conflict with the container. In practice the Docker port takes precedence and doesn't conflict, because of how it's implemented using iptables. But your public container IP will still respond on all the non-conflicting ports, e.g. ssh.
I discovered that --net=host might not always be the best option, as it might allow users to shut down the host from the container! In any case, it turns out that the reason I couldn't properly do it from inside was because network configuration was designed to be restricted to sessions that begun with the --privileged=true argument.
You can set up SkyDns with service discovery tool - https://github.com/crosbymichael/skydock
Or: Simply create network interface and publish docker container ports in it like here https://gist.github.com/andreyserdjuk/bd92b5beba2719054dfe
I want to create a shell script that can change the hostname of my Ubuntu permanently. Whenever I use the hostname New_hostname command, it returns to the original hostname after I restart the machine.
I found out that the only way I can change this permanently is by modifying the file in /etc/hostname and save it. Is there some way I can do this using a shell script only? I also have a password.
The hostnamectl combines setting the hostname via the hostname command and editing /etc/hostname. Unfortunately, editing /etc/hosts still has to be done separately.
hostnamectl set-hostname <new-hostname>
Type
echo "myNewHostName" > /etc/hostname
in any shell with root access near you..
You may also want to take a look at the file /etc/hosts, cf. http://pricklytech.wordpress.com/2013/04/24/ubuntu-change-hostname-permanently-using-the-command-line/.
In Ubuntu 18.04 LTS
Hostname changing via SSH is reverted after reboot in Ubuntu 18.04. Make permanent change as following way.
1. Edit /etc/cloud/cloud.cfg
sudo nano /etc/cloud/cloud.cfg
Set preserve_hostname to true
preserve_hostname: true
2. Run hostnamectl
hostnamectl set-hostname new-host-name
3. Reboot
sudo reboot
Change hostname permanently without reboot
/etc/hosts
127.0.0.1 persistent_host_name
/etc/hostname
persistent_host_name
Apply changes Immediately
$ sudo hostname persistent_host_name
Check changes
$ hostname
persistent_host_name
Typically, you would need to change it in these files:
/etc/hostname
/etc/hosts
If you are using some advanced printers, also here:
/etc/printcap
This is why I would recommend doing it manually - but search the old hostnames first. To find all occurrences in /etc:
sudo grep -iRI "_OLDHOSTNAME_" /etc 2>/dev/null
Then change the _OLDHOSTNAME_ in every occurrence.
Done.
To chaneg the Hostname permanet in ubuntu machine
Go to :
#vim /etc/hostname
Type the hostname inside the file you want to set for the machine
Then save and the file
After saving the document run this command
# hostname -F /etc/hostname
Then edit the /etc/hosts file
#vim /etc/hosts
type the ip hostname inside the file
Then Logout of of the machine and relogin into the machine
If you just want to change host name, because its getting displayed as a command prompt in the terminal. Then you can replace \h in PS1 with "desired_host_name" in ~/.bashrc
Like in ~/.bashrc put this line at end of file:
export PS2="continue-> ";
export PS1="\u#3050:~$ ";
Change Hostname on Ubuntu 18.04
Definition
A hostname is a label that identifies a machine on the network. You shouldn’t use the same hostname on two different machines on a same network.
Prerequisites
User should have a sudo privileges
Change the Hostname
Change the hostname using hostnamectl command. If you want to change the hostname to new_hostname
sudo hostnamectl set-hostname new_hostname
It will not change the hostname directly. You want to preserve the changes permanently then you have to edit cloud.cfg file
sudo nano /etc/cloud/cloud.cfg
# This will cause the set+update hostname module to not operate (if true)
preserve_hostname: true
Save the file and close your editor.
Verify your Changes
You can verify your changes using command hostnamectl it will show new_hostname under Static hostname
PS: Source Link
How to get the vendor information of my NIC on top of Ubuntu? I wanna get its vendor, type and things like that? Any shell commands available? Thanks in advance.
Try something like this -
sudo lshw -C network
OR
sudo ethtool -i eth0