How to create .htpasswd file for nginx using chef - nginx

I am new to chef and I am trying to generate a .htpasswd file to store user hash, I went through some links
but this is not helping.
I need ngnix to secure Kibana and I want to generate a password for users using openssl. I have created a template file as .htpasswd_temp.erb
it looks like this:
<% #kibana_user.each do |user| %>
<%= user %>:
<% end %>
and my recipe is:
kibana_configs = node['kibana']['kibana_auth']
template 'path/to/.htpasswd' do
source '.htpasswd_temp.erb '
variables(
kibana_user: kibana_configs['kiba_user']
)
end
I have created one role file where I have defined all default attributes(including kiba_user).
Above code adds users to .htpasswd file but I have no idea how to generate password using openssl. Openssl command works fine using execute resource but execute resource does not work inside template resource, thus does not get reflected in .htpasswd file.I am really confused. Thank so much for your help ^^

the following recipe snippet might by handy for you...
it assumes that you are familiar with encrypted data bag and that you have stored your credentials in a data bag named creds, with encrypted item named nginx that holds username and password keys.
htpassed_file = '/root/.htpasswd'
chef_gem 'htauth'
ruby_block 'create .htpasswd' do
block do
require 'htauth'
creds = data_bag_item('creds', 'nginx')
HTAuth::PasswdFile.open(htpassed_file, HTAuth::File::CREATE) do |pf|
pf.add(creds['username'], creds['password'])
end
FileUtils.chmod 0o600, htpassed_file
end
end

You can use recipe for that as well https://github.com/redguide/htpasswd with combination of data bags to encrypt your password (as well as username).
htpasswd "/etc/nginx/htpassword" do
user "foo"
password "bar"
end

Related

Glassfish Change Admin Password

How can I change the admin password for a Glassfish Domain using a password file? I know the conventional method of manually typing the password upon prompt.
However I want to change the admin password using a script where in I do not have to manually type the password.
This is possible, but you will need 2 password files if you want to script this fully in the easiest way.
Create a temporary file (tmpfile in my example) which will hold the current password (blank by default) and the desired new password:
AS_ADMIN_PASSWORD=
AS_ADMIN_NEWPASSWORD=myNewPassword
Now create a password (pwdfile in my example) file which will contain the changed admin password:
AS_ADMIN_PASSWORD=myNewPassword
You can then use the files to change the password using the commands below, making sure to use tmpfile when changing the password, then pwdfile afterwards
$PAYARA_PATH/bin/asadmin start-domain
$PAYARA_PATH/bin/asadmin --user $ADMIN_USER --passwordfile=/opt/tmpfile change-admin-password
$PAYARA_PATH/bin/asadmin --user $ADMIN_USER --passwordfile=/opt/pwdfile enable-secure-admin
$PAYARA_PATH/bin/asadmin restart-domain
This example was adapted from the way the Payara Server dockerfile works
For anyone still interested in manually setting the admin account password:
I tried to generate the contents of the "admin-keyfile" located in "glassfish/domains/{ACTIVE_DOMAIN_NAME}/config/admin-keyfile" based on the current implementation of the Payara Repo. This file (as the data source for the FileRealm) is used to authenticate the admin user when accessing the admin interface under port 4848.
Each line of this text file represents an account and is structured as
USERNAME;PASSWORD;GROUPS
The field "PASSWORD" is prefixed with a hash algorithm keyword (wrapped in curly braces, e.g. "SSHA" or "SSHA256") followed by a BASE64 encoded hash of the concatenated salted hash and the salt value itself (some random bytes):
{SSHA}BASE64(SHA(password,salt),salt)
Long story short: If you want to generate user accounts manually you could for example use the following Python script:
import hashlib
from base64 import b64encode
from secrets import token_bytes
from getpass import getpass
username = 'admin' # input('Username: ')
plainTextPassword = getpass()
randomSalt = token_bytes(8)
passwordHash = hashlib.sha256()
passwordHash.update(plainTextPassword.encode('utf-8'))
passwordHash.update(randomSalt)
passwordDigest = passwordHash.digest()
# cryptic range reflects the strange implementation... feel free to change it to "range(98)"
# https://github.com/payara/Payara/blob/6488cbdc90fd0f6c42de6a42affcd09f697be715/nucleus/common/common-util/src/main/java/org/glassfish/security/common/SSHA.java#L108
for run in range(2, 101):
passwordHash = hashlib.sha256()
passwordHash.update(passwordDigest)
passwordDigest = passwordHash.digest()
saltedHashAndSalt = b64encode(passwordDigest + randomSalt).decode('utf-8')
result = '{0};{{SSHA256}}{1};asadmin'.format(username, saltedHashAndSalt)
print(result)
Insert the console output into the "admin-keyfile" and (re)start your server.
As far as I know, it is impossible to change it via a file as a parameter for security reasons.
You can consider an alternative solution (pipe) but the confirmation of the password is always necessary. https://docs.oracle.com/cd/E19798-01/821-1758/change-admin-password-1/index.html

Encrypt and Decrypt documents through asp.net application

My asp.net application is in Web Server A and displays and let download MS-Word or PDF documents that are stored in Web Server B.
For security reasons, I was advised to encrypt and decrypt those documents when serving them up on the webserver A.
Could anyone give me some clue on how to do that?
I've never seen some utility before. My code just give value to a link control and let the user to click on it to display a MS-Word or PDF document, like:
Dim RemoteFolder As String
Dim RemoteFileName As String
RemoteFolder = "http://192.168.32.98/Application/Documents/"
RemoteFileName = "MyWordDocument.doc"
lnkOpenDocument.NavigateUrl = RemoteFolder + RemoteFileName
Using SSL might help, that protects all request/responses between the two servers. Otherwise .Net does have a encryption/decryption library under System.Security:
http://support.microsoft.com/kb/307010 also see this previous post What's the easiest way to encrypt a file in c#?
you can always grab the file from the user, encrypt using one of the above methods, and drop the encrypted file on webserver B. when reading it rather than link directly to the .doc file, link to another asp.net page, pass the ID of the file into that new page and have it pull the file from Webserver B decrypt it and display to the user.

Reading information from a password protected site

I have been using readLines() to scrape information from a website in an R tutorial. I now wish to extract data from my own website (specifically the awstats data) however the domain is password protected.
Is there a way that I can pass the url for the specific awstats data I require with a username and password.
the format of the url is:
http://domain.name:port/awstats.pl?month=02&year=2011&config=domain.name&lang=en&framename=mainright&output=alldomains
Thanks.
If it is indeed a http basic access authentication, the documentation on connections provides some help:
URLs
Note that https:// connections are
only supported if --internet2 or
setInternet2(TRUE) was used (to make
use of Internet Explorer internals),
and then only if the certificate is
considered to be valid. With that
option only, the http://user:pass#site
notation for sites requiring
authentication is also accepted.
So your URL string should look like this:
http://username:password#domain.name:port/awstats.pl?month=02&year=2011&config=domain.name&lang=en&framename=mainright&output=alldomains
This might be Windows-only though.
Hope this helps!
You can embed the username and password in the url like :
http://userid:passw#domain.name:port/...
This you can try to use with readLines(). If that doesn't work, you can always try a workaround using url() to open the connection :
zz <- url("http://userid:passw#domain.name:port/...")
readLines(zz)
close(zz)
You can also download the file and save it somewhere using download.file()
download.file("theurl","/path/to/file/filename",method="wget")
This saves the file on the local path that is specified.
EDIT :
as csgillespie said, you shouldn't include your username and password in the script. If you run scripts with source() or interactively, you could add eg :
user <- readline("Give the username : ")
passw <- readline("Give the password : ")
Url <- paste("http://",user,":",passw,"#domain.name...")
readLines(Url,...)
When running from the commandline, you could pass the arguments after --args and access them using commandArgs (see ?commandArgs)
If you have access to the box, you could always just read the awstats log files. If you can ssh into the box, then you could easily sync the latest file using rsync.
The slight snag with using
http://username:password#domain...
is that you are putting your password in an R script - best to avoid this. Of course you can secure it the script, but it only takes one slip. For example,
Someone asks you a similar question and you publish your script
The url http://username:password#domain... will(?) now show up on your server logs
...
Formatting the url as http://username:password#domain... for use with download.file didn't work for me, but R.utils provides the function downloadFile that works perfectly:
require(R.utils)
downloadFile(myurl, myfile, username = "myusername", password ="mypassword")
See #joris-meys answer for a way to avoid including your username and password in plain text in your script.
EDIT Except it looks like downloadFile just reformats the URL to http://username:password#domain...? Hmm...

How to change WebDAV password locally

I can't figure out how to change the webdav password. I've done some searching, found many resources of how to add a new user to webdav, but nothing about changing password. Anyone know?
Passwords are stored in webdav.htpasswd file.
If you open it, you will see an entry like this
wampp:XAMPP with WebDAV:bc7f2b670e7e965e307feb30492e642e
That's the entry for user wampp: in realm XAMPP with WebDAV: with password which is encrypted.
To change password, you should use htdigest.exe.
See manual. It is used to create and update user authentication files. You should find in the bin directory of xampp installation.
To do that, do :
htdigest.exe "pathto/webdav.htpasswd" "XAMPP with WebDAV" yourusername
This will be returned:
Adding user yourusername in realm "XAMPP with WebDAV"
You will then be asked for the password for yourusername
New password: yourpassword
Re-type new password: yourpassword
Reference: http://www.apachefriends.org/f/viewtopic.php?f=16&t=38897
Replace the content of the file C:\Program Files\xampp\security\htpasswd.webdav with your username, a colon and the password. Note: Everyone who can see this file can see the password!
Assuming you're talking about doing a password change at the server from a client, I don't believe WebDAV supports such a transaction.
You'd use something like a shell logon or a Web-based admin page to do this.
This always struck me as odd for a lot of network services, for example FTP or email. It seems to be common though.

asp.net media protection

Does anyone know a good practice of securing media for asp.net?
I need to host a variety of media that require permission to a view a specific image/video. i.e. a specific user may or may not have permission to view a media file - and this fact may be changed on the fly.
I don't care if they can download a media file that they have access to, I just don't want them to even be aware of items they should not have access to.
I've already considered url obfuscation - this seems quite lame to me.
I have form authenticated users (and I'm not willing to change this).
I would like to keep the media file folder structure unrelated to permissions.
Build an HttpHandler that all media must be accessed through. Then, prior to retrieving the file and sending it down to the user, you can perform any validations that you'd like. Keep all of your media outside of the main wwwroot path, or deny access to that folder using permissions.
More info on this topic here:
http://www.15seconds.com/Issue/020417.htm
I use an xml file like this to set which users/groups have access to a file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root[
<!ELEMENT file ANY>
<!ATTLIST file name ID #REQUIRED>
]>
<root>
<file name="file.doc" users="155,321" groups="grp5" />
<file name="file2.doc" users="321" groups="" />
</root>
files are stored above http root so they cannot be accessed by URL.
When a user tries to access GetFile.aspx?file=file.doc I load the XML, get the line with
XmlNode xnFile= XML.GetElementById(wantedFile);
, then I call a function
HasAccess(Context.User, xnFile);
Which checks if the user is logged in and compares the permissions, and if it is ok for this user to have the file, I read the files from disk and write them out with
FileInfo thisFile = new FileInfo(secretLocation + wantedFile);
Response.Clear();
Response.Buffer = false;
Response.BufferOutput = false;
Response.ClearContent();
Response.ClearHeaders();
Response.AddHeader("Content-Length", thisFile.Length.ToString());
Response.AddHeader("Content-disposition", "filename=" + thisFile.Name);
Response.ContentType = "application/none";
Response.WriteFile(secretLocation + wantedFile);
Response.Close();
Response.End();
Response.ClearContent();
Response.ClearHeaders();
Actually now I have more than a thousand files, and I think of writing the file data to the database as the XML got corrupted twice in 5 years, probably due to crashes or simultaneous use.
From your comment in the Spikolynn answer
I'm puzzled - how is this different than obfuscation? Would an authenticated user be able to share an image (which they are authorized for) with another authenticated but unauthorized user?
I guess that you try to prevent unauthorized sharing of media.
This is something a lot of companies (Microsoft, Apple, IBM, etc) have put considerable amount of money to solve. The solution was DRM, and now they are removing it, because it failed.
So, my answer is that you can not prevent sharing if the user is willing to put some effort to avoid it.
You can just keep the honest people honest by applying some techniques as Spikolynn or Lusid explain in their answers.
I'd suggest a table holding the files to which each user has access:
UserID int
FileID varchar
then a table for your files:
FileID UniqueIdentifier
FileType char(4) <- so you know which extension to use.
etc...
On the hard drive, name the file the FileID (UniqueIdentifier) and the FileType (the extension, eg. .jpg). The fileID in the permissions table will hold the UniqueIdentifier generated in the other table.
You can pass this via the URL knowing with relative safety that the user won't be able to guess the name of any other file.
Update: this is, by the way, much simpler than writing an HttpHandler or dealing with file permissions. However, while the chances of someone guessing another file name are infinitesimal it is not airtight security as one user may give another one access to the file.
brownpaperpackage.aspx?id={guid}
In the Load event of media.aspx, you verify the user is authenticated, then verify the user has the right to view the media, and if they do, then load the media as a stream and feed it to the page's Response as Spikolynn demonstrated.
Why do it this way? Its simple to code and you get all the benefits of ASP.NET and IIS' authentication services, from which you can find the user requesting the media. Its trivial to map that user to an access list for your media objects. And the Page has the request object right there. You're also hiding the name of the media, so you can't tell what's going on from the URL.
How do you keep people from accessing your media directly? Your media files cannot be stored in the IIS virtual directory. If they are, there's a possibility that they can be downloaded directly. You can store them in a database as a byte array (blob) or store them on disk outside of the web virtual directory. Users must go through ASP.NET to access the files
How do you keep track of what users have access to what media? You keep track of your users thorugh asp.net membership. That means each user has an ID in the aspnet_users table. Create a table for your media with an id and a filename (or a blob containing the actual media). Then you just need to create a third table that connects the two. This table would contain a user id and a media id, signifying this user can view this media. With the user id (from asp.net Membership) and the media id (from the URL) you just need to
select count(*) from UserMedia where UserId = #UserGuid and MediaId = #MediaIdFromUrl
and if the count > 0 the user can view the media.
An example of how you'd use the URL:
<asp:image
runat="server"
ImageUrl="brownpaperpackage.aspx?id=53a2ea4(snip)76ca8b" />

Resources