In past I've connected to VPN via Linux in Windows perfectly with python by using the following code:
import win32ras
hdl, retcode = win32ras.Dial (None, None, (vpn_name, ip, "", username, password, ""), None) #changing 'ip' will connect to that server ip
win32ras.HangUp (hdl) #This disconnects the connection
So this works perfectly fine in windows with python but now I want to do it in ubuntu with python and I'm not sure how to do this at all. I want to do the same, define a VPN name and change its IP on connecting and input via username/password, if there's any other way, like directly connecting to the VPN without even making one then that's obviously better.
I'm finding the solution on internet as of now, will update if I find something.
How about using the Linux PPTP Client: http://pptpclient.sourceforge.net/ ?
A few options for calling it from Python:
1) Call it as a command-line tool using subprocess: https://docs.python.org/2/library/subprocess.html
2) Build it as a library and call it via Cython: http://cython.org/
3) Build it as a Python package (and for bonus points, make it available to others!): https://docs.python.org/2/extending/extending.html
Related
I have two linux computers with fixed IP addresses:
A print server, whereby the connected printer is shared via CUPS.
(The server has the IP address "192.168.1.2" and the printer is called "test_printer".)
A computer, on which a python application is running, that should be able to use this print server.
Unfortunately, the printer propagation via CUPS seems not to work reliably (possibly due to the structure of the network).
Can I send print jobs directly from a python program to the CUPS print server?
If so, can you please provide a small example?
In theory, I would just send correctly formatted data to the IP address + port, but I didn't get it to work ...
Here are the approaches I have found so far and my problems with them:
command 'lpr'
import subprocess
lpr = subprocess.Popen("usr/bin/lpr", stdin=subprocess.PIPE) # on some distros the command is 'lp'
lpr.stdin.write("hello world\n")
lpr.stdin.close()
Relies on the printer propagation via CUPS.
python module pycups
import cups
with open("/home/user/Documents/some.txt", "w") as f:
f.write("hello world\n")
conn = cups.Connection()
conn.printFile("test_printer", "/home/user/Documents/some.txt", "some_title", {})
Before I can use a printer, I'll have to add it first, which in turn relies on the propagation via CUPS.
Also I didn't get conn.addPrinter() to work.
python module python-escpos / python-printer-escpos
import escpos.printer
p = escpos.printer.Network("192.168.1.2", port=631) # port 9100 seems not to work.
p.text("hello world\n")
p.close()
Probably the most promising approach ... unfortunately it doesn't print anything and throws an exception on closing.
# The traceback was produced in the interactive shell.
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/user/.local/lib/python3.6/site-package/escpos/printer.py", line 214, in close
self.device.shutdown(socket.SHUT_RDWR)
OSError: [Errno 107] Transport endpoint is not connected
python module pkipplib / pyipptool
Unfortunately, there seems not to be a working python3 library that implements the Internet Printing Protocol (IPP) in 2018.
I use python 3.6.7.
The print server uses CUPS 2.2.1.
Not being a Python programmer, I cannot provide any sample code.
But I can give you some other hints:
Your assumption, that "in theory, [....] just send correctly formatted data to the IP address + port" is wrong.
If you send something, you have to "talk IPP" to the CUPS server (yes, via the IP address + port 631). But just sending a file is so much less than talking IPP.
Else, you could use 'netcat IPaddress port-no < filename' to print to any CUPS queue (which would be a huge security issue).
So you HAVE to use some IPP-capable library, if you want to integrate your program with IPP/CUPS
One alternative could be that you let your program do the "IPP talk to CUPS" by a CLI tool which is capable of doing so.
Have a look at the ippsample code of the Printer Working Group (PWG) which designed the IPP. That is in "beta" still but already fully usable. All its binaries are command line (CLI) utilities:
It provides the ippfind helper tool. If you run it without any parameters, it will print a list of available IPP Services (print servers and/or printer devices) by printing their respective IPP URIs.
It provides an ippserver command line, which can start up a fully-fledged, you guessed it, IPP Server exposing any feature you want.
Then there is ipptool included as an IPP Client. You could run 'ipptool -f myprintfile -t -v ipp://cupsserver/printers/test_printer print-job.test' to send "myprintfile" to the queue "test_printer" on "cupsserver" (given with example IPP URI ipp://cupsserver/printers/test_printer) and watch it talk IPP to CUPS while it does so.
See also my ASCIIcast "[TUTORIAL] IPP Sample Software (made with an AppImage)" here.
{https://asciinema.org/a/155588 }. Hint: if it plays too fast to follow and understand the screens in time, use the 'pause' button, read at your own speed, then resume playing.
Issue : I'm a noob with Paramiko, trying to run some commands from a python script (on personal machine) on a remote server. The remote server doesn't need a password to connect to.
For example, if I do
root#[IPaddress] on my Mac, I'm successfully able to connect to the remote server via MacbookPro terminal.
However, I'm trying to do this inside a Python script using Paramiko, and no matter what I do, I get an Authentication error or No Authentication methods available.
I went through Paramiko AuthenticationException issue but the answers there are vague for me to implement without significant experience with Paramiko. Help?
This is my code:
import paramiko
import os
from paramiko import SSHClient
#Borrowed from the linked post
class SSHClient_noauth(SSHClient):
def _auth(self, username, *args):
self._transport.auth_none(username)
return
#How do I implement?
ssh = SSHClient()
sshc = SSHClient_noauth()._auth(username="root") #Where's the ssh obj passed?
sshc.set_missing_host_key_policy(paramiko.AutoAddPolicy())
sshc.connect("10.xxx.xxx.xxx")
Well, not to let the negative vote bog me down.
Tried doing sshc.connect(remoteIP, username=username, password="") and it worked. In case someone has been stuck for over an hour or two trying to get this working, especially for work, you might want to try putting in a "" instead of None.
I am using a telit he910g card. it is connected to my PC directly using a miniPCI slot.
I am using it for 3G internet connection and A-GPS/GPS services.
My system is running linux mint 17.1, the 3G connection is handled using the network manager APP and works great. The 3G connection is started and handled using a module that is part of a program I am writing.
The code I am using in order to connect to the serial port is this:
def _connect_to_device(self):
""" Connect to a serial port """
try:
self._device = serial.Serial(self._filename, baudrate=self._baud_rate)
except StandardError, e:
raise StandardError("Couldn't connect to GPS device. Error: %s" % str(e))
When I use the python program alone it works great. But when I try and use it while the 3G is on i cant connect to the serial device. The wierd thing is that if I try to connect to it using a program like "minicom" while 3G is turned on it DOES work.
So my question is: how can I make both run and work together? since now they are mutually exclusive.
thanks to all who help. :)
Glad you found a way round your problem. Just for completeness:
Normally, serial ports can be opened by multiple processes.
If one of them does ioctl(,TIOCEXCL) on the open file then further opens will return EBUSY until everyone closes the device. Only root can get past this and open the device at all times.
If root opens the device and does an ioctl(,TIOCNXCL), then other processes can open the device too.
In python, TIOCNXCL isnt defined anywhere, but you can do the ioctl (eg on stdin) with:
import fcntl
TIOCEXCL = 0x540c # from /usr/lib64/perl5/asm-generic/ioctls.ph
TIOCNXCL = 0x540d
print fcntl.ioctl(0, TIOCNXCL)
Ok, so it is solved.
the issue was that the telit module has 2 ports /dev/ttyACM0 (high speed) and /dev/ttyACM3 (lower speed).
I tried to connect to the high speed one, but apparently the 3G uses that one and it causes contentions.
So moving to use the lower speed port in my script solved the issue.
I am writing an application that interacts with numerous systems, specifically with switches,
i am trying to implement a function that will enable me to retreive logs from a specific switch using Fabric (python)
in a real session to the switch i would need to first run "enable" (and press enter key) and then run "debug generate dump" command.
using fabric.operations.run() i can only issue one command at a time,
using fabric.operations.open_shell() is not an option since i need to parse the output and also close the connection once it finishes.
Can someone assist on this?
THANKS!!
Here is an example of the code:
def getSwitchLog(self, host, port, username, password):
env.host_string = "%s:%s" % (host, port)
env.user = username
env.password = password
command = 'enable \r debug generate dump'
run(command, shell=cli, pty=True, combine_stderr=True, timeout=120)
shell=cli - because the switch does not run bash and 'cli' is the appropriate value in this case
\r should have sent "enter" key essentially sending 1. enable 2. enter 3. debug generate dump
this method works if i switch run with open_shell
but it seems run ignores \r
I was able to achieve what i need using:
command = 'sshpass -p admin ssh admin#switchIP cli \"enable\" \"show version\"'
fabric.api.local(command, capture=True, shell=None)
however this method is not robust as fabric.api.run() and also requires the running node to have sshpass installed
This is an example of the output from the switch CLI as the commands entered interactively (keyboard) without fabric
[standalone: master] > enable
[standalone: master] # debug generate dump
[standalone: master] # debug generate dump Generated dump sysdump-SX6036-1-20130630-104051.tgz
[standalone: master] #
thanks.
So working with a session state isn't something Fabric does. Every call is a new session. There are some other project that try and get around this, one being fexpect, but since you're attempting to query a switch I don't believe that will work. Since fexpect (last i knew) uploads a expect script which it then runs to the remote machine.
What you might have better luck with though is pxssh from the pexpect module. It allows ssh+expect like work simple enough. It's outside Fabric, but more likely to work for you right out of the gate I think.
work with robot-framework based on 'paramiko'. It has more simple API (write/read_unitl/read_all) to interact with your switch shell.
http://robotframework.org/SSHLibrary/latest/SSHLibrary.html
I wrote a simple python script using the SocketServer, it works well on Windows, but when I execute it on a remote Linux machine(Ubuntu), it doesn't work at all..
The script is like below:
#-*-coding:utf-8-*-
import SocketServer
class MyHandler(SocketServer.BaseRequestHandler):
def handle(self):
data_rcv = self.request.recv(1024).strip()
print data_rcv
myServer = SocketServer.ThreadingTCPServer(('127.0.0.1', 7777), MyHandler)
myServer.serve_forever()
I upload it to the remote machine by SSH, and then run the command python server.py on the remote machine, and try to access to xxx.xxx.xxx.xxx:7777/test with my browser, but nothing is printed on the remote machine's teminal...any ideas?
UPDATE: Problem solved, it's a firewall issue, thanks you all.
You are binding the server to 127.0.0.1, the IP address for localhost. This means the server will only accept connections originating from the same machine; it won't recognize ones coming from another machine.
You need to either bind to your external IP address, or bind to a wildcard address (i.e. don't bind to any particular IP address, just a port). Try:
myServer = SocketServer.ThreadingTCPServer(('0.0.0.0', 7777), MyHandler)
You are binding to 127.0.0.1:7777 but then trying to access it through the servers external IP (I'll use your placeholder - xxx.xxx.xxx.xxx). 127.0.0.1:7777 and xxx.xxx.xxx.xxx:7777 are different ports and can be bound by different processes IIRC.
If that doesn't fix it, check your firewall, many hosts set up firewalls that block everything but the handful you are likely to use
Try with telnet or nc first, telnet to your public ip with your port and see what response you get. Also, why are accessing /test from the browser? I don't see that part in the code. I hope you have taken care of that.