I am looking at trying to create a python server, which allows me to run root commands on a Centos Server remotely, I would also like the server to be able to respond with the result's of the command.
I have found another question on here which has a basic python server, however it throws a error, the code is:
#!/usr/bin/python
import os
import socket
print " Loading Bindings..."
settings = {}
line = 0
for each in open('/root/actions.txt', 'r'):
line = line + 1
each = each.rstrip()
if each <> "":
if each[0] <> '#':
a = each.partition(':')
if a[2]:
settings[a[0]] = a[2]
else:
print " Err # line",line,":",each
print " Starting Server...",
port = 12345
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(("", port))
print "OK."
print " Listening on port:", port
while True:
datagram = s.recv(1024)
if not datagram:
break
print "Rx Cmd:", datagram
if settings.has_key(datagram):
print "Launch:", settings[datagram]
os.system(settings[datagram]+" &")
s.close()
When i run using python vzctl.py. I get the following error:
File "vzctl.py", line 9
each = each.rstrip()
^
SyntaxError: invalid syntax
Does anyone have any idea of the error, and if it would be possible to add the function of the server responding with the output of the command.
You can see the source of this script at : How can I have a PHP script run a shell script as root?
Thanks,
Ashley
you need to keep indentation at the same level for each nested statement throughout your code.
On a different note: why not using TwistedMatrix?
Related
I am trying to learn Django through the course offered by MichiganX on edX. My problem is that the lesson skipped some details, and without them I cannot get the code to work.
Code looks like this:
from socket import *
def createServer():
serversocket = socket(AF_INET, SOCK_STREAM)
try:
serversocket.bind(('localhost', 9000))
serversocket.listen(5)
while 1:
(clientsocket, address) = serversocket.accept()
rd = clientsocket.recv(5000).decode()
pieces = rd.split('\n')
if len(pieces) > 0:
print(pieces[0])
data = "HTTP/1.1 200 OK\r\n"
data += "Content-Type: text/html; charset=UTF-8\r\n"
data += "\r\n"
data += "<html><body>Hello World</body></html>\r\n\r\n"
clientsocket.sendall(data.encode())
clientsocket.shutdown(SHUT_WR)
except KeyboardInterrupt:
print("\nShutting down...\n");
except Exception as exc:
print("Error:\n");
print(exc)
serversocket.close()
print('Access http://localhost:9000')
createServer()
We were also told to build a simple web browser that would connect us to the server we build and it should return "Hello World!", code for it looks like this:
import socket
mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
mysock.connect(('127.0.0.1', 9000))
cmd = 'GET http://127.0.0.1/romeo.txt HTTP/1.0\r\n\r\n'.encode()
mysock.send(cmd)
while True:
data = mysock.recv(512)
if len(data) < 1:
break
print(data.decode(), end = '')
mysock.close()
First problem is that nowhere in the course there's a mention of romeo.txt, it just popped out of nowhere. They told us to just run the code, but it does nothing. I googled how to launch server so in my command windom I launched it from the directory my server file is located but whenever I try to connect with above web browser (even if I delete "romeo.txt") from code I get error 404.
I know I'm missing something, I know that just launching server from the directory my files are located are not enough, lesson doesn'n explain how to do it but in order to progress in the next lesson I need to do it. Can anyone help me? Sorry if the question is stupid but I'm stuck for two hours already and I have no idea what else can I do.
These two programs are creating sockets.
The first program acts as the server and the second program acts as the client. The first program is waiting for someone to connect to it as in this line serversocket.accept(), while the second program tries to connect to the server as in this line mysock.connect(('127.0.0.1', 9000)).
Your problem is you are not running the server while running the client. The solution is first start the server, keep it running then start the client.
It should work like so, in one cmd / terminal:
python server.py
In other cmd / terminal:
python client.py
Replace server.py and client.py with original file names.
I am automating few configuration steps on CentOS. In order to do so i need to reboot the system also. I am invoking the "reboot" command the via python pexepct, however i need to wait till the systems boots up for remaining script to executes. For that i am have written this small piece of code.
while True:
result = commands.getoutput("ping -c 4 192.168.36.134")
if result.find("Unreachable") == 1:
result = False
print 'Rebooting the Systems.'
else:
result = True
print 'Connected!'
break
Is there any better way to do this? Also, can we achieve this with the pexepct itself?
You can try this:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# wait host to finish reboot, check specific port connection (usually ssh port if you want to exec remote commands)
while True:
try:
s.connect(('hostname', 22))
print "Port 22 reachable"
break
except socket.error as e:
print "rebooting..."
# continue
s.close()
This example is more effective then using ping
On a vm I used the command: nc -l -p 8221 -e /bin/bash and made a python3 script:
def netcat():
print ("starting connection")
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("192.168.1.60", 8221))
while True:
user = input("what to send?: ")
s.sendall(bytes(user, "utf-8"))
time.sleep(5)
word = "bob"
data = s.recv(4096)
if data == b"":
pass
else:
data = data.decode("utf-8")
print ("Received:", repr(data))
print ("Connection closed.")
s.shutdown(socket.SHUT_WR)
s.close()
netcat()
this script doesn't work. By don't work I mean when I run a command with my python script, lets say "pwd", it just loads but never runs.
When, instead of running the python script I would run nc 192.168.1.60 8221, it would work fine. Any ideas why?
From input()'s documentation:
The function then reads a line from input, converts it to a string
(stripping a trailing newline), and returns that.
But Bash is operating in canonical mode and won't process input till a new line arrives. This won't happen, leading to recv blocking forever.
add a + '\n' after the user = input("what to send?: ") to fix it.
import socket
import struct
def get_default_gateway_linux():
with open("/proc/net/route") as fh:
for line in fh:
fields = line.strip().split()
if fields[1] != '00000000' or not int(fields[3], 16) & 2:
continue
return socket.inet_ntoa(struct.pack("<L", int(fields[2], 16)))
def getNetworkIp():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(('bt', 0))
return s.getsockname()[0]
print "Your Machine IP has been detected as "+getNetworkIp()
print "Your Gateway IP has been detected as "+get_default_gateway_linux()
the above code neither shows any error nor any output when executed in backtrack 5 R3
please help me regarding this code!
Your 2 print statements are tabbed/spaced. Remove them and it will work as I have confirmed this to work on CentOS 6.5:
def getNetworkIp():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(('localhost',0))
return s.getsockname()[0]
print "Your Machine IP has been detected as "+getNetworkIp()
print "Your Gateway IP has been detected as "+get_default_gateway_linux()
This may be too simple to be true, but the last two lines are part of getNetworkIp(), since they are indented as such.
I even get an indentation error from Python when I try this.
Note that when I move those last 2 print statements out to column 0, I get another error, because I get a 'name or service not known' error ... but that's probably an old Linux/Python problem, or need root.
Anyway, try un-indenting those last two print statements.
I'm new to Python programming and I'm trying to create a server and a client. I still want to be able to type something from the keyboard so i can close the server from the server by typing 'exit'. I've taken samples codes from various sites to get to where I'm at in socket programming and this code.
However, whenever I run the code I get the following error message:
The host name of this machine is 127.0.0.1
The IP address of the host is 127.0.0.1
Server now awaiting client connection on port 2836
im right before the select
Traceback (most recent call last):
File "/root/Server_2.py", line 42, in <module>
inputready, outputready, exceptready = select.select(input, [], [])
TypeError: argument must be an int, or have a fileno() method.
>>>
I was reading around that to get passed this (in Windows) is to remove the sys.stdin because Windows only accepts sockets. I'm trying to write this code in Linux. I've tried all sorts of things to try to get it to work and I'm all out of resources and ideas to try. Below is the server code:
import socket #import socket module
import select
import sys
host = "127.0.0.1"
print ("The host name of this machine is " + host)
hostIP = socket.gethostbyname(host) # get host IP address
print ("The IP address of the host is %s" % (hostIP))
port = 2836 # Reserve the port for the server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((hostIP, port)) # This server to a port
s.listen(4) # Now wait for client connection
print("Server now awaiting client connection on port %s" % (port))
#WINDOWS ONLY ACCEPTS SOCKETS FOR SELECT(), no standard in
input = [s, sys.stdin]
running = 1
while running:
print("im right before the select")
# when there's something in input, then we move forward
# ignore what's in output and except because there's nothing
# when it comes to sockets
inputready, outputready, exceptready = select.select(input, [], [])
print("i'm here na")
# check who made a response
for x in inputready:
if x == s:
print(s)
#handle the server socket
client, address = s.accept()
print("connection comming in")
input.append(client)
elif x == sys.stdin:
# handle standard input
stuff = sys.stdin.readline()
if stuff == "exit":
running = 0
else:
print("you typed %s" % (stuff))
else:
#handle all other sockets
data = x.recv(1024)
print("i received " + data)
if data:
if data == "exit":
x.close()
input.remove(x)
running = 0
else:
x.send(data)
print("I am sending %s" % (data))
else:
x.close()
input.remove(x)
s.close()
Any help or ideas would be greatly appreciated. Thanks!!
Well I know you asked this 7 years ago, but I had similar questions so I would figure I answer you. I'm still working and bugfixing a program that has the same functionality, but one thing I do know is that the lists that are the arguments in select.select() need to be file descriptors (ints).
So if you have this block
input = [s, sys.stdin]
running = 1
while running:
print("im right before the select")
# when there's something in input, then we move forward
# ignore what's in output and except because there's nothing
# when it comes to sockets
inputready, outputready, exceptready = select.select(input, [], [])
The first thing I'd say is change your read list to not be input. You'll likely get some clashing with the input() function, which may cause confusing bugs. After that, you want the values to be file descriptors. So that first line should be
inputSockets = [s.fileno(), sys.stdin.fileno()]
Then when checking which socket is ready to ready, you would want to do it like this
for x in inputready:
if x == s.fileno():
# Read from your s socket
elif x == sys.stdin().fileno():
# Read from stdin
else:
'''
Here you would want to read from any other sockets you have.
The only problem is your inputSockets array has ints, not socket
objects. What I did was store an array of actual socket objects
alongside the array of file descriptors. Then I looped through the
list of sockets and found which socket's .fileno() matched x. You could
probably be clever and use a dict() with the filenos as key and socket as
value
'''
I just came across this while writing a unix domain socket (UDS) interface. The server socket id is used to accept incoming client connections. That is pretty much all it does. Once the client is accepted, reading uses its own file descriptor. Something like this works:
conn = None
inputReady, Null, Null = select.select(inputSockets, [], [])
for x in inputReady:
if x == s.fileno():
# accept incoming connect and add to poll list
conn, addr = s.accept()
inputReady.append(conn.fileno())
elif x = sys.stdin.fileno():
# read whole line and remove newline
cmd = sys.stdin.readline()[:-1]
...
elif conn and x == conn.fileno():
data = conn.recv(msglen)
if data:
....
else:
# connection has ended, remove from poll list and close
if conn.fileno() in inputReady:
inputReady.remove(conn.fileno())
conn.close()