I'm using the Perl Net::SCP module to SCP tarballs to a remote server.
The remote server does not have a static IP, so every time the IP address changes the sending machine would need to accept the host key.
This breaks my script, as now I have to manually accept the host key each time the IP changes.
Is there a way I can have Net::SCP bypass host key checking?
I saw an option with Net::SCP::Expect, but I'm not sure if I would be required to use this module.
Solution
Yes, you can do that with the module Net::SCP::Expect in the following way (unix system assumed):
#!/usr/bin/perl
use strict;
use warnings;
use Net::SCP::Expect;
my $scp = Net::SCP::Expect->new(
host => 'localhost', # or target IP address
user => 'username',
password => 'mysecretpass',
auto_yes => 1, # automatically pass a 'yes' string to any yes/no questions
timeout => 5,
option => 'UserKnownHostsFile=/dev/null StrictHostKeyChecking=no' # the trick
);
# now send the file
$scp->scp('file.tar', 'TargetDirectory/') || die "scp() failed: $!\n";
Explanation
SCP actually uses SSH, so whenever the remote identity/fingerprint changes, the connection is no longer permitted because of security reasons. As you can probably imagine, this is for your own security because you could also be the victim of a "man in the middle attack" or similar things. Your machine has most likely saved all known fingerprints in the following file:
~/.ssh/known_hosts
And this causes the problem for you. In the Perl script above you can see how the options UserKnownHostsFile=/dev/null and StrictHostKeyChecking=no are passed to the constructor. These are actually SSH options, which can be either specified on the command line or in your machine's SSH configuration file. Since SCP uses the same options, you can pass them to the module and therefore completely bypass the identity check in your case.
Why does it work?
By replacing(*) the known_hosts file with /dev/null, you basically give it an empty file that cannot be modified. This allows you to completely ignore the safety check and your file will get sent as expected.
(*): of course it doesn't get replaced in the filesystem, but the module will just use it as the temporary location/path
Related
I am trying to change the IP address set to a particular site in the host file.
For example :
# 123.123.123 www.google.com
# 456.456.456 www.google.com
I want to make a test that I enter Google through 123.123.123 and as the program changes and open Google through 456.456.456.
Changing the servers manually is removing the # from the beginning of the line.
I do not want to use selenium grid with some machines since any machine on another server do not have the resources for it.
I want to change this in the same machine while running through the code.
As the etc/hosts file is picked up immediately by the system without a restart you can manipulate or even completely overwrite this file during your run.
The trouble is that to edit the hosts file you need 'root' rights and you are actually changing the behaviour of your host system. In order to prevent this you might think about running in a docker environment but if that is not possible you can do something like this with root access:
/etc/hosts file
# 123.123.123 www.google.com
# 456.456.456 www.google.com
as part of your test run:
# at start of run
sed -i .bak 's/# 123.123.123/123.123.123/g' /etc/hosts
# do other tests now
# later when stuff has changed
sed -i .bak 's/123.123.123/456.456.456/g' /etc/hosts
Something like this?
i want to use tcl command fcopy to copy a file from windows host machine to a vm location. What I get is I need a inchannel and a outchannel. Here inchannel in the filestream and out channel is some kind of socket where a server is runing maybe. I am at bay regarding the server part and how the file will be saved from the socket in a vm path. Please guide with some resource link.
If you have two filenames (and both are currently visible, which depends on how things are mounted and which is totally out of baseline Tcl's control) use file copy. Otherwise, if you can arrange to get the contents of the file somehow (perhaps by using ssh hostaddress cat) then you use chan copy (which fcopy is the old name for).
set srcFD [open |[list ssh hostaddress cat "src/file.ext"] "r"]
set dstFD [open "dst/file.ext" "w"]
chan copy $srcFD $dstFD; # Or: fcopy $srcFD $dstFD
close $srcFD
close $dstFD
I'm running a Centos virtual machine using Vagrant. The machine seems to run properly, but when I try to sync Perforce I can see the following error:
[vagrant#vagrant-c5-x86_64 ~]$ /perforce/p4 sync -f ...
Perforce client error:
Connect to server failed; check $P4PORT.
failed.TCP connect to perforce.xxx.com:1666
Servname not supported for ai_socktype
I have read this http://www.ducea.com/2006/09/11/error-servname-not-supported-for-ai_socktype/ and tried to set the ports in /etc/services, but it didn't work. I am not even sure if the problem is Perforce or OS related.
Any hints?
I had this problem with a Tornado/Python app. Apparently, this can be caused by the port being interpreted as a string instead of an integer. So in my case, I needed to change my startup script to force it to be interpreted as an integer.
application = tornado.web.Application(...)
application.listen(int(port))
Are you able to enter your client ? before trying to sync the files, try to create a perforce client:
p4 client
Maybe it's not the host:port that is the issue, but other flags in the connection string that interrupt.
I personally received the exact same error, but it was a Perforce issue.
The reason is, Perforce has its own priority when it's looking for its P4USER/P4PORT/... configuration.
ENV variables ( run export )
if a P4CONFIG variable was specified somewhere it can search in a file ( like .perforce in the current/upper directory )
Problem was, even though it first search for an ENV variable - the P4CONFIG file might override it.
So my $P4PORT ENV variable had a connection string X, but the .perforce file had a connection string Y.
Removing the P4PORT from my local .perforce file - solved this issue.
in example:
$~] echo $P4PORT;
rsh:ssh -2 -q -a -x -l p4ssh perforce.mydomain.com
$~] cat .perforce
# P4PORT="rsh:ssh -q -a -x -l perforce.mydomain.com /bin/true"
P4USER="my_user"
Also remember that Perforce will search for the $P4CONFIG file ( if configured one ) in the entire directory hierarchy upwards, so even if you don't have the file in the current directory - it might be found in an upper directory, and there - you might have a $P4PORT configuration that you didn't expect..
Put trailing slash, e.g.:
http://perforce.xxx.com:1666/
Instead of:
http://perforce.xxx.com:1666
In my case I got like this error in golang language, i changed my port type from string to int and works fine
My hosted scripts have been moved and no longer work.
The specified CGI application
misbehaved by not returning a complete
set of HTTP headers.
I notice that someone at my host company has modified my scripts so that where I used to have
use lib 'd:/myorig/LIB';
I now have
use lib '//newhost/LIB';
Should this work?
I tried 1800 INFORMATION's suggestion and ran the minimal script of
#!perl -w
use lib '//whatever/lib';
print "success";
...which gave the same result.
Update: ysth's suggestion of FatalsToBrowser did indeed reveal more information. It looks like the path (added by someone from the hosting company) might be wrong.
Update2: The hosting company now says that these scripts, unchanged from the previous host mind, are throwing lots of syntax errors. "Since we cannot debug your scripts for you we suggest you contact the original programmer and ask them for help". <grinds teeth>
Partial Resolution: The hosting company finally realised they hadn't set permissions correctly. They still aren't right, and (aargh) they don't allow site owners to set folder permissionsn, not even on folders within their own sites.
I don't know if it should work or not, but my intuition is that it would be okay. However, the two use lib lines you posted are not equivalent.
# go to the 'd' drive and use the 'myorigLIB' directory on that drive
use lib 'd:/myorigLIB';
# go to the 'newhostLIB' server - no path is specified - this looks invalid to me
use lib '//newhostLIB';
Perhaps you need to specify the path to the share on the server? Also, you might need to look at permissions? Maybe the user the CGI is running as cannot access that network path?
Also, you could write a simple (non CGI) program to test your theory and just run it:
#!perl -w
use lib '//whatever/lib';
print "success";
Then just run that on the server if you can and see what happens.
No the path is incomplete it needs both a server name and a complete path. It is a bad practice as well because it requires that two machines be monitored rather than one for your application to function.
The specified CGI application misbehaved by not returning a complete set of HTTP headers.
That's a non-error. If you are lucky, your hosting company will make an error log available to you that will show the actual error that perl is dying with. If not,
consider using
use CGI::Carp "fatalsToBrowser";
for testing. (If you are paranoid (which is not a bad thing to be), you will refrain from leaving that enabled once you are done testing, since errors can commonly provide information about your code or even your database that may help a black hat exploit security holes.)
I know I ran into trouble trying to use mapped drives and unc paths from apache because the apache user was not allowed to use network drives. That was difficult to figure out -- but it's possible to do it. That may be a related problem.
#!perl -w
print "HTTP/1.0 200 OK\nContent-Type: text/plain\n\n";
my $path = "//whatever/lib";
print "\nExists ", -e $path;
print "\nDirectory ", -d $path;
print "\nReadable ", -r $path;
print "\nListing:\n";
print "\t$_\n" for glob "$path/*";
What is the command-line equivalent of "Switch Port Client User" as found in the p4win gui client?
I am already logged under one port but now I am attempting to connect to a different port on the same server in order to access a separate source control file depot. I assume it would involve using:
p4 login
However, reading the 'help' for 'login' does not show an option to specify the port #. Both user name and client name would remain the same but just need to change the port #.
The P4PORT configuration variable stores the Perforce server name and port number to connect to. You can set this value as an environment variable or, if you're using Windows, in the registry using 'p4 set':
p4 set P4PORT=perforce:1669
To see what the current value of P4PORT is:
> p4 set P4PORT
P4PORT=perforce:1669
If you want to do it generically for any P4 command then the general form can be found via "p4 help usage".
In a nutshell,
p4 -p <your port> login
will do what you asked for. Note from the usage help that you can specify most things from the command line such as client spec, username, password, etc.
E.g:
p4 set P4PORT=1666
From the help:
C:\> p4 help environment
Environment variables used by Perforce:
Variable Defines For more information see
-------- ------- ------------------------
P4AUDIT name of server audit file p4d -h
P4CHARSET client's local character set p4 help charset
P4COMMANDCHARSET client's local character set for
command line operations p4 help charset
P4CLIENT name of client workspace p4 help client
p4 help usage
P4CONFIG name of configuration file Command Reference Manual
P4DIFF diff program to use on client p4 help diff
P4DIFFUNICODE diff program to use on client p4 help diff
P4EDITOR editor invoked by p4 commands p4 help change, etc
P4HOST name of host computer p4 help client
p4 help usage
P4JOURNAL name of server journal file p4d -h
P4LANGUAGE language for text messages p4 help usage
P4LOG name of server log file p4d -h
P4MERGE merge program to use on client p4 help resolve
P4MERGEUNICODE merge program to use on client p4 help resolve
P4PAGER pager for 'p4 resolve' output p4 help resolve
P4PASSWD user password passed to server p4 help passwd
P4PORT port client connects to p4 help info
or server listens on p4d -h
P4ROOT server root directory p4d -h
P4TARGET target server for proxy Command Reference Manual
P4TICKETS location of tickets file Command Reference Manual
P4USER user name p4 help usage
PWD current working directory p4 help usage
TMP, TEMP directory for temporary files Command Reference Manual
See 'p4 help set' for details specific to Windows. The syntax for
setting an environment variable depends on the OS/shell. Note that many
shells allow the setting of shell variables separate from environment
variables - Perforce cannot see the shell variable, only the environment
variable.
If you are a typical user then the only variables of interest are
$P4CLIENT, $P4PORT and $P4PASSWD.
C:\> p4 help set
set -- Set variables in the registry (Windows only)
p4 set [ -s -S service ] [ var=[value] ]
'p4 set' sets the registry variables used by Perforce on Windows
platforms. Normally, the variable 'var' is set to 'value'.
If 'value' is missing, the variable 'var' is unset. Without
any arguments at all, 'p4 set' list variable settings.
The -s flag causes 'p4 set' to set variables for the whole system
rather than for the user. You must have NT administrator powers
to use this.
The -S service flag causes 'p4 set' to set variables for the named
service. You must have NT administrator powers to use this.
Currently, registry variable entries may be overridden by environment
variables and (in some cases) flags on the command line.
See 'p4 help environment' for a list of environment/registry variables.
You can use a configuration file to set the port that Perforce connects to for each project.
First, create a text file that contains the Perforce configuration variables you want to set for the project. For example, to set the value of P4PORT, the contents of the file would look like this:
P4PORT=hostname:1234
Name the file something descriptive like .p4config and place it in the root of the project folder. Do this for each one of your projects, changing the variables as necessary. Use the same filename.
Then, set the value of P4CONFIG to the name of your configuration files, e.g.
p4 set P4CONFIG=.p4config
This will make Perforce look for configuration values in a file of that name in the current directory or any parent directory, so you don't have to change your configuration variables manually every time you switch projects.