Does a capistrano deploy.rb file contain server credentials? - php

This is my first time using Capistrano and I am getting server authentication errors right at the start of my deploy:setup stage. I am a PHP user using rvm on a mac.
I noticed my deploy.rb file does not contain the password to my server. It only contains the password to my private git repo. Is there an attribute available for setting the server password so my connection could authenticate?
Do deploy.rb files list server credentials?

I'd like to refer you to a related discussion. Point in case: It's better to setup publickey authentication for your servers, it saves you from having your credentials stored in plain text and it is safer to begin with.
If you use github for your git hosting, you can use your publickey there as well. Be sure to use ssh_options[:forward_agent] = true to forward your publickey to the server when deploying.
If you really want to set your user and password, I believe you can do it as follows:
set :user, "sshuser"
set :password, "sshpassword"
set :scm_passphrase, "gitpassword"
More info can be found at github help/capistrano

The previous answer covers good info about deploy and i agree it is better to setup public keys.
But if you have password issues, try to add this line:
default_run_options[:pty] = true
to your deploy.rb file, so you allow Capistrano to prompt for passwords.

#Amit Erandole (in reply to [ip_address_omitted] (Net::SSH::AuthenticationFailed: root), app_name_ommitted (Errno::ETIMEDOUT: Operation timed out - connect(2)):
Looks like root access over ssh is not allowed on the server (and generally not recommended). Try it again with a valid user or turn root access on in sshd_config (PermitRootLogin yes).
But as was already mentioned by HectorMalot, create an ssh-key and forget about the passwords. ;)

Related

mysqli connection db user and password settings

i am trying to figure out if there is a way to make a password recovery system that actually hides the "connection.php" with all the mysqli db username and password. is this possible?
most of the tutorials i found have the "connection.php" file shown to make the connection to the database and it can be viewed from source which makes the the database login info visible. can someone help me with this or point me in the right direction to go about this please?
example:
<?php
$connection = mysqli_connect('localhost', 'root', 'Rvm#i[9)0?~=');
if (!$connection){
die("Database Connection Failed" . mysqli_error($connection));
}
$select_db = mysqli_select_db($connection, 'pixelw3p_demo');
if (!$select_db){
die("Database Selection Failed" . mysqli_error($connection));
}
?>
this is in the connection.php file which needs to be added as a
require_once('connection.php');
now this php file can be seen in the source then you know which php file to look for to get the database info. any way all of this can be hidden so my db isn't vulnerable?
To put it straight: there is absolutely nothing wrong in having credentials in a PHP file. What everyone is talking about is "NEVER store passwords, API keys, or other sensitive information" in a file included in the version control (e.g. git).
A PHP file by itself is no worse than ENV, INI, JSON, XML, YAML or whatever. Actually a PHP file is even slightly better, as it doesn't need to be put strictly above the document root. And also, using PHP for the configuration allows a better integration with your application.
Whereas what is really essential, is having all the application settings in a separate file with which is removed from the version control, so it will never make it into a repository or another server.
Given all the above, to make your configuration file separated from the source code:
add the config.php line in .gitignore (in case you are using git)
create a file called config.sample.php with all variables set to empty values like this
return [
'db' => [
'host' => '127.0.0.1',
'username' => '',
'password' => '',
'dbname' => '',
'port' => 3306,
],
];
add it to the version control
in your application bootstrap file have a code like this
if (!file_exists('config.php'))
{
throw new \Exception('Create config.php based on config.sample.php');
}
$config = require 'config.php';
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli(...$config['db']);
$mysqli->set_charset('utf8mb4');
then, as suggested, create config.php on the every server your application runs, each with its own set of values
What you have to understand, this routine is obligatory for any file format, config.ini icluded. And it's this routine that makes your passwords secure and portable, not a file format you choose.
To be blunt, most of the tutorials you've found are probably absolute garbage and everything they're telling you is wrong. Few of them actually address serious security concerns, and those that do usually either gloss over it, or fail to address the issues by promoting best practices.
It's not hard, but it can be tricky to do right. You need to keep in mind a bunch of things.
NEVER store passwords, API keys, or other sensitive information in your source code. Use configuration files, especially simple ones in INI, JSON or even XML format. PHP has functions for reading all of these quickly and easily.
NEVER store configuration files in a place that's within your public "web root", that is a place that could be accessed by someone tinkering with the URL to probe for files like these. Even if you have rules in your web server configuration to block these requests those rules might be disabled by accident, a problem that often manifests when you redeploy your application to a new server that isn't configured correctly.
NEVER check your production configuration files into version control. This is how you leak API keys and passwords to would be attackers. For instance, accidentally pushing an Amazon AWS key to a public GitHub repository is often swiftly punished by someone who will use that key to spin up hundreds of expensive instances. It doesn't matter if repositories are private: These can be cloned by people and made public without your knowledge.
ALWAYS do what you can to minimize the number of places where critical passwords, API keys and other credentials are stored. Use a secure storage system like 1Password as a "vault" where the contents are properly and thoroughly encrypted, not something like a Google Doc which could be compromised.
ALWAYS burn all passwords, API keys, and other credentials stored on a server in the event of a compromise. If you don't know how much access had or how long they've had access, re-issue new passwords, generate new API keys, and be absolutely certain the old credentials no longer work. Do not assume you have time to fix this. You might not. Immediately and permanently fix the problem when you realize you've got an issue.
The simplest answer here is to make a config.ini file with this information in it that's saved outside the web root and kept only on the server. Don't download it. Don't copy it. Don't touch it unless you need to. This helps avoid costly, painful mistakes.
A .htaccess file is usually impossible to display in browsers, but mind that depends on webserver settings. It's the default in Apache, and also in NGINX (where a .htaccess file has no functionality), but be very aware other webservers could have other defaults, and may display the contents of a .htaccess.
Contrary: a php.ini file is usually not configured to be rejected at HTTP requests!
Also if PHP processing fails, you end up with credentials in plaintext.
Anyway, I consider the .htaccess method as reliable as using htpasswd for authentication or limiting access.
In Apache's .htaccess this works:
php_value mysqli.default_host localhost
php_value mysqli.default_user obelix
php_value mysqli.default_pw zKSIOSwjsiyw9263djcaleP982WLdDU3kzn6
php_value mysqli.default_db broccoli
Then in PHP it's as easy as:
$db = mysqli_connect();
$db->select_db('menhirdb');
It's anyway better than storing credentials in sourcecode.
If you think your webserver performance sucks because a .htaccess is read line by line at each HTTP query, than you better put it in httpd.conf
That's anyway the way I would do it, but then like:
php_admin_value mysqli.default_host localhost
php_admin_value mysqli.default_user obelix
php_admin_value mysqli.default_pw zKSIOSwjsiyw9263djcaleP982WLdDU3kzn6
php_admin_value mysqli.default_db broccoli
The benefit of using 'php_admin_value' is automatically that .htaccess values can't overwrite them. Which is a great security benefit, I think. As I've witnessed more than once that vulnerable CMS systems wrote hostile .htaccess files.

How to tell if phpseclib sftp response is a challenge with a password request when key doesn't match

Recently someone inadvertently changed the keyfile used for my ssh/sftp to a remote server. I deduced this when I tried to ssh to the server from the command line and I got challenged with a password request, which indicated that the key was no longer recognised.
How would I make my php program detect an unexpected password challenge? Currently I have this:
$sftp = new SFTP(self::DOMAIN_NAME);
$Key = new RSA();
$private_rsa_key = file_get_contents('/home/ddfs/.ssh/' . self::KEY_FILE);
$Key->loadKey($private_rsa_key);
$rc = $sftp->login(self::USER, $Key);
$errors = $sftp->getSFTPErrors();
At the moment I see $rc is set to FALSE and $errors is an empty array.
SSH initiated password change requests
SSH has a mechanism built into it for password resets. My reading of RFC4252 § 8 implies that SSH_MSG_USERAUTH_PASSWD_CHANGEREQ packets should only be sent in response to a "password" SSH_MSG_USERAUTH_REQUEST but who knows how the OpenSSH devs interpreted that section of the RFC.
Since you're doing public key authentication phpseclib would be sending a "publickey" SSH_MSG_USERAUTH_REQUEST so it seems like SSH_MSG_USERAUTH_PASSWD_CHANGEREQ wouldn't be a valid response, but again, who knows.
If the server did respond with a SSH_MSG_USERAUTH_PASSWD_CHANGEREQ packet than you could do $sftp->getErrors() (instead of getSFTPErrors) and look for one that starts with SSH_MSG_USERAUTH_PASSWD_CHANGEREQ:. Maybe even do $sftp->getLastError().
getSFTPErrors returns errors with the SFTP layer - not the SSH2 layer. SFTP as a protocol doesn't know about authentication - that's handled entirely by the SSH layer. ie. it's not SFTP errors you'd want to look at but SSH errors.
Reference code: https://github.com/phpseclib/phpseclib/blob/1.0.7/phpseclib/Net/SSH2.php#L2219
Other possible password request mechanisms
It's possible that password request isn't coming from SSH's built-in authentication mechanism. It's possible you're getting a SSH_MSG_USERAUTH_SUCCESS response from the "publickey" SSH_MSG_USERAUTH_REQUEST.
At this point I can see two possibilities:
It could be a banner message that you're seeing. You can get those by doing $sftp->getBannerMessage().
It's possible you're only seeing this error when you SSH into the server as opposed to SFTP'ing into it. ie. it's possible you wouldn't see the error unless you did $ssh->exec() or $ssh->write(). At this point the "error" could be communicated to you via stderr or stdout.
To know for sure I'd have to see the SSH logs. The phpseclib logs may or may not be sufficient. I mean you could do $sftp->exec('pwd'); or $sftp->read('[prompt]'); but my guess is that you're not already doing that. If you wanted to go that route you could do define('NET_SSH2_LOGGING', 2); and then echo $sftp->getLog() after you do either $sftp->exec() or $sftp->read().
The PuTTY logs might be more useful. To get them you can go to PuTTY->Session->Logging, check the "SSH packets" radio button and then connect as usual.
Unfortunately, OpenSSH does not, to the best of my knowledge, log the raw / decrypted SSH2 packets so OpenSSH isn't going to be too useful here.

Disk space of a device on the same network

So the core thing what I'm trying to do is get the disk space from a other Device that is on the same network.
I use the PHP function disk_total_space() for this. I'm using the connecting string \\192.168.0.1\c$.
So in total I would have:
disk_total_space('\\\\192.168.0.1\\c$');
However, I have some questions about this connection string, to begin with:
With what protocol does this 'URL' connect?
why does it need a $ at the end of the driver?
Now I also need to give username and password with my connection string. However I don't know how to fuse this with the connection string I have.
I tried to give the username and password with an FTP-protocol and an HTTPS-protocol, but none seems to work.
https:\\\\username:password#\\\\192.168.0.1\\c$
ftp:\\\\username:password#\\\\192.168.0.1\\c$
As you might notice I'm new to these protocols, so I hope anyone could explain this to me.
I know nothing about php, but it seems like to answer this question you need no php knowledge... Hope this helps:
1. With what protocol does this 'url' connect?
This is called UNC Path. See more details from wiki: Path (computing)
Quote:
A UNC path describes the location of a volume, directory, or file.
The format for a UNC path is \\server\volume\directory\file and is not case-sensitive.
2. Why does it need a $ at the end of the driver?
The $ stands for a hidden share, see more from Microsoft Knowledge Base
3. For your last question, 'Passing UNC username and password within a UNC path'
There is an answer to a similar question on SuperUser.
Quote answer from #grawity's answer
On Windows, you cannot put credentials in UNC paths. You must provide them using net use, runas /netonly, or when asked by Windows. (If you have some programming skills, you can store the SMB password as a "domain credential" using CredWrite(), which is equivalent to checking the "Remember password" box in Windows.)
On Linux, it depends on the program.
GNOME's Gvfs accepts the user#host syntax, but appears to completely ignore the password. (However, you can store it in GNOME Keyring beforehand.)
smbclient uses the same UNC syntax as Windows; however, it has an --authentication-file option from which credentials could be read.
Both programs above are using libsmbclient, and can use Kerberos authentication instead of passwords: run kinit user#YOUR.DOMAIN and use smbclient -k //host/share. This is more secure than password authentication.
Note that putting passwords into URIs is deprecated, and you should not rely on it being supported anywhere.

Access network share with PHP5.2 + IIS7.5

I'm using php 5.2 with IIS7.5.
I have a network share on a NAS that is username and password protected. I cannot disable or change authentication info on the NAS. I need to be able to access that network share via php.
I've done the following:
Created new user in windows whose username and password matches those on the NAS.
Created IIS application pool that uses this same auth info.
Created a web.config file inside of the php app directory with an impersonation turned on, using the same auth info.
identity impersonate="true" password="ThePass" userName="TheUser" />
Turned on ASP.NET impersonation in the application authentication in IIS.
None of this seemed to work with this simple line of code in php:
$dir = opendir("\\someservername\somesharename");
Warning: opendir(\someservername\somesharename) [function.opendir]: failed to open dir: No error in C:\websites\site\forum\testing.php on line 7
So, I decided to test the configuration with ASP.NET.
string[] diretories = System.IO.Directory.GetDirectories("\\someservername\somesharename");
The asp.net test worked perfectly.
Going further down the rabbit hole, I ran phpinfo() and checked the username info in it. Down in the "Environment" section of phpinfo, I found the "USERNAME" item. Its value was "TheUser," as was what I expected.
Everything points to the system being configured correctly until I tried:
echo get_current_user();
Which returned, "IUSR." That surely isn't what I expected.
So, how in the world do I get php + IIS7.5 to read from a foreign network share?
Update:
Thanks to a few of the answers, I've added
$result = shell_exec("net use o: \\\\pathToServer\\27301 /persistent:yes 2>&1");
Which returns a success. I'm still getting the error on opendir. I tried another test and used is_dir. This returned false on my newly created mapped drive.
var_dump(is_dir("o:\\"));
// Prints: bool(false)
UPDATE
I ran the script from the command line when logged in as the user that created. The scripts executes correctly. Could this take us back to get_current_user() which returns IUSR? I tryied getmypid() which returned a process ID. I cross referred that process id with the task manager and found that it was for php-cgi.exe, running under the custom user account that I made.
The recommended way to access a network share in PHP is to "mount" it. Try to connect your share as a network drive.
Btw. your command is wrong
$dir = opendir("\\someservername\somesharename");
You have to use 4 "\" because it's the escape character
$dir = opendir("\\\\someservername\somesharename");
NOTE: get_current_user() returns the owner of the process on IIS
You can try a test by mapping it like
$command = "net use $drive \"\\\\$ip\\$share\" $smb_password /user:$domain\\$smb_username";
$result = shell_exec($command);
on opendir you need to have \\\\$server_name\\$share try with 4 '\' and if mapping like that works and 4 '\' is failing on opendir. You may have credentials not matching.
If you map it this way new user you created in windows whose username and password matches those on the NAS will have rights on mapped drive that way you do not need to worry about the scope.
Had the same problem on a similar system. Solved this by going to web site > Authentication > Anonymous Authentication > Change IUSR to whatever your username is or use Application Pool user if correctly configured.

php access network path under windows

within PHP (XAMPP) installed on a Windows XP Computer Im trying to read a dir which exists on a local network server. Im using is_dir() to check whether it is a dir that I can read.
In Windows Explorer I type \\\server\dir and that dir is being shown.
When I map a network drive a can access it with z:\dir as well.
In PHP I have that script:
<?php if( is_dir($dir){ echo 'success' } ) ?>
For $dir I tried:
/server/dir
//server/dir
\server\dir
\\server\dir
\\\\server\\dir
and
z:\dir
z:\\dir
z:/dir
z://dir
But I never get success?
Any idea?
thx
I solved it by changing some stuff in the registry of the server as explained in the last answer of this discussion:
http://bugs.php.net/bug.php?id=25805
Thanks to VolkerK and Gumbo anyway!
I love stackoverflow and their great people who help you so incredibly fast!!
EDIT (taken from php.net):
The service has limited access to network resources, such as shares
and pipes, because it has no credentials and must connect using a null
session. The following registry key contains the NullSessionPipes and
NullSessionShares values, which are used to specify the pipes and
shares to which null sessions may connect:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters
Alternatively, you could add the REG_DWORD value
RestrictNullSessAccess to the key and set it to 0 to allow all null
sessions to access all pipes and shares created on that machine.`
add RestrictNullSessAccess=0 to your registery.
You probably let xampp install apache as service and run the php scripts trough this apache. And the apache service (running as localsystem) is not allowed to access the network the way your user account is.
A service that runs in the context of the LocalSystem account inherits the security context of the SCM. The user SID is created from the SECURITY_LOCAL_SYSTEM_RID value. The account is not associated with any logged-on user account.
This has several implications:
...
* The service presents the computer's credentials to remote servers.
...
You can test this by starting the apache as console application (apache_start.bat in the xampp directory should do that) and run the script again. You can use both forward and backward slashes in the unc path. I'd suggest using //server/share since php doesn't care about / in string literals.
<?php
$uncpath = '//server/dir';
$dh = opendir($uncpath);
echo "<pre>\n";
var_dump($dh, error_get_last());
echo "\n</pre>";
Try the file: URI scheme:
file://server/dir
file:///Z:/dir
The begin is always file://. The next path segment is the server. If it’s on your local machine, leave it blank (see second example). See also File URIs in Windows.
Yes, I know this is an old post, but I still found it, and if anyone else does...
On Windows, with newer servers, verify the SMB is installed and enabled on the target machine.

Categories