Αυτή τη στιγμή σπουδάζω δοκιμές διείσδυσης και προγραμματισμό σε Python. Θέλω απλώς να μάθω πώς θα μπορούσα να εκτελέσω μια εντολή Linux στην Python. Οι εντολές που θέλω να εκτελέσω είναι οι εξής:
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port 8080
Αν απλά χρησιμοποιήσω την print
στην Python και την τρέξω στο τερματικό θα κάνει το ίδιο με την εκτέλεση σαν να την πληκτρολογούσες εσύ ο ίδιος και να πατούσες Enter?
Μπορείτε να χρησιμοποιήσετε την os.system()
, ως εξής:
import os
os.system('ls')
Ή στην περίπτωσή σας:
os.system('echo 1 > /proc/sys/net/ipv4/ip_forward')
os.system('iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port 8080')
Ακόμα καλύτερα, μπορείτε να χρησιμοποιήσετε την κλήση subprocess's, είναι ασφαλέστερη, ισχυρότερη και πιθανώς ταχύτερη:
from subprocess import call
call('echo "I like potatos"', shell=True)
Ή, χωρίς να καλέσετε το κέλυφος:
call(['echo', 'I like potatos'])
Αν θέλετε να καταγράψετε την έξοδο, ένας τρόπος για να το κάνετε είναι ο εξής:
import subprocess
cmd = ['echo', 'I like potatos']
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
o, e = proc.communicate()
print('Output: ' + o.decode('ascii'))
print('Error: ' + e.decode('ascii'))
print('code: ' + str(proc.returncode))
Συνιστώ υψηλά να ορίσετε ένα timeout
στο communicate
, και επίσης να συλλάβετε τις εξαιρέσεις που μπορεί να λάβετε κατά την κλήση του. Αυτός είναι ένας πολύ επιρρεπής σε λάθη κώδικας, οπότε θα πρέπει να περιμένετε να συμβούν λάθη και να τα χειριστείτε ανάλογα.
Η πρώτη εντολή απλώς γράφει σε ένα αρχείο. Δεν θα την εκτελούσατε ως εντολή κελύφους, επειδή η python
μπορεί να διαβάζει και να γράφει σε αρχεία χωρίς τη βοήθεια ενός κελύφους:
with open('/proc/sys/net/ipv4/ip_forward', 'w') as f:
f.write("1")
Η εντολή iptables
είναι κάτι που μπορεί να θέλετε να εκτελέσετε εξωτερικά. Ο καλύτερος τρόπος για να το κάνετε αυτό είναι να χρησιμοποιήσετε το subprocess module.
import subprocess
subprocess.check_call(['iptables', '-t', 'nat', '-A',
'PREROUTING', '-p', 'tcp',
'--destination-port', '80',
'-j', 'REDIRECT', '--to-port', '8080'])
Σημειώστε ότι αυτή η μέθοδος δεν χρησιμοποιεί επίσης ένα κέλυφος, το οποίο είναι περιττή επιβάρυνση.
Ο γρηγορότερος τρόπος:
import os
os.system("your command here")
Αυτή δεν είναι η πιο ευέλικτη προσέγγιση- αν χρειάζεστε περισσότερο έλεγχο πάνω στη διεργασία σας από το "εκτελέστε την μία φορά, μέχρι να ολοκληρωθεί, και μπλοκάρετε μέχρι να εξέλθει", τότε θα πρέπει να χρησιμοποιήσετε την ενότητα subprocess
αντί γι' αυτό.