Check for blocked ports

Sometimes, enterprise firewalls are nasty. They simply won’t let you to connect to your desired ports. Moreover, you don’t have neither read nor write access to their control panels and of course unblocking ports implies a pile of paperwork you could circumvent if you’d only knew what is open.

Luckily, the people from positon.org jhas a service we can use with this piece of code:


for I in $(seq 1 65535);do if [[ ${I} -ne 21 ]] && [[ ${I} -ne 22 ]];then curl -s http://portquiz.net:${I};[[ "$?" -eq 0 ]] && echo "$I" >> openports.txt;fi;done

At the end there is a file named openports.txt that contains a list of ports you can access from behind your firewall.

Posted in Linux | Tagged , , , | Leave a comment

Automatically fill Java’s SSL keystore with remote certificates

When it comes to SSL, Java gets a tad bit picky. In order to get around that, the Razorfish Germany DevOps team (which we are a part of) created a nifty little script to enable Java to talk to SSL-enabled servers without the well-known pain. It’s quite easy to use. At minimum, you need to pass it a hostname and the keystore password. Additionally, you can set a port (if not 443) and an alternative keystore location.

Here’s the source, it’s licensed under GPLv3. As usual, the code is as-is so don’t call on us if you set your house on fire.

the script below might be downloaded here as well.

[code language=”bash”]
#!/bin/bash

####
# Script: rzr-retrieve-certchain
# Description: Retrieves the certificate chain from a given SSL server and imports it into Java’s keystore.
# Author: Marcus Pauli<marcus.pauli@razorfish.de>
# License: GPL v3 (see: http://www.gnu.org/licenses/gpl-3.0.txt)
####

# the well known usage report
function usage {
echo -e "Usage: $0 -h hostname -s storepassword [-p port] [-k path/to/keystore/file]"
[[ "$#" -ne "0" ]] && echo "$@"
exit 1

}

# we need arguments so we break if none are provided
[[ "$#" -eq "0" ]] && usage

while getopts "h:p:s:" o; do
case "${o}" in
h)
REMOTEHOST=${OPTARG}
;;
k)
KEYSTORE=${OPTARG}
;;
p)
declare -ri REMOTEPORT=${OPTARG}
;;
s)
STOREPASS=${OPTARG}
;;
*)
usage "None or wrong arguments given"
;;
esac
done
shift $((OPTIND-1))

# here we check whether the correct parameters have been set
[[ -z ${JAVA_HOME} ]] && usage "No JAVA_HOME set. Exiting."
[[ -z ${REMOTEHOST} ]] && usage "You forgot to set a hostname. Exiting"
[[ -z ${STOREPASS} ]] && usage "You forgot to set a key store password. Exiting"

# if not given, we set some defaults
[[ -z ${REMOTEPORT} ]] && REMOTEPORT=443
[[ -z ${KEYSTORE} ]]KEYSTORE="${JAVA_HOME}/jre/lib/security/jssecacerts"

# this is the name of our tempfile and the first part of an keystore alias
CRTFILE=$(echo ${REMOTEHOST} | sed ‘s/\.//g’)

while read line ;do
# YAY is our separator so we know when a certificate ends
if [ "${line}" != "YAY" ];then
echo "${line}" >> ${CRTFILE}
else
# If we can’t add any new data, the file is complete. First we need to bring it into the right layout
sed -i "s/.\{76\}/&\n/g" ${CRTFILE}
# Then fetch a fingerprint
FINGERPRINT_CERT=$(openssl x509 -fingerprint -in ${CRTFILE} -noout | sed ‘s/.*=//g’)
# If the fingerprint does not already exist in the keystore, we add it
if [[ $(${JAVA_HOME}/bin/keytool -list -keystore ${KEYSTORE} -storepass ${STOREPASS} | grep -c ${FINGERPRINT_CERT}) -eq 0 ]]; then
${JAVA_HOME}/bin/keytool -import -alias ${CRTFILE}-$(date +%s) -file ${CRTFILE} -keystore ${KEYSTORE} -storepass ${STOREPASS} -trustcacerts -noprompt
fi
# Of course, we clean up
rm ${CRTFILE}
fi
# This is the command to receive the whole certificate chain and to alter it on the fly so we can parse it correctly
done < <(echo "" | openssl s_client -showcerts -connect ${REMOTEHOST}:${REMOTEPORT} 2>/dev/null | sed -ne ‘/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p’ | tr -d ‘\n’ | sed -e ‘s/—–BEGIN CERTIFICATE—–/\n—–BEGIN CERTIFICATE—–\n/g’ -e ‘s/—–END CERTIFICATE—–/\n—–END CERTIFICATE—–\nYAY\n/g’)
# It could well be that we did not clean up properly, so we make sure everything is by now.
[[ -f ${CRTFILE} ]] && rm ${CRTFILE}
[/code]

Posted in Linux | Tagged , , , , , , , , | Leave a comment

Gitlab 6.5.1, OpenLDAP and SSH-Keys

Quite a while ago, we played around with Web-UIs for Git and stumbled over Gitlab. However, there was no current gentoo ebuild and we were too lazy to create our own, so we took the latest version available and installed that one.

The only problem is that GitLab stores everything in its MySQL database whereas SSH authenticates against our OpenLDAP. Therefore, we needed a hack.

First of all, we created a MySQL user that is only allowed to run the following statement SELECT `key` FROM `gitlab.keys`.
Of course, we created a LDAP user that can only change the sshPublicKey attributes for the gitlab user.
Then we created a script (see below).
Finally, we set up a cronjob: * * * * * /usr/local/bin/siczb-cron-gitlab

[sourcecode language=”shell” title=”/usr/local/bin/siczb-cron-gitlab”]
#!/bin/bash

###
# Copyright by sächsische Informations-Compagnie zu Berlin
###

### SET PARAMETERS
LDAP_FILE="/tmp/ldap-$(date +%s)"
MYSQL_FILE="/tmp/mysql-$(date +%s)"
MD5_FILE="/tmp/gitlab.md5"

MYSQL_DB=example_db
MYSQL_USER=example_user
LDAP_USER="uid=example_user,ou=example_ou,dc=example,dc=com"
LDAP_PASS="example_password"
LDAP_GITLAB_USER="cn=example_git,ou=example_ou,dc=example,dc=com"

### HIC SUNT LEONES
mysql -s -u${MYSQL_USER} ${MYSQL_DB} -e "SELECT \`key\` FROM \`keys\`;" | tail -n +1 > ${MYSQL_FILE}
MD5_NEW=$(md5sum ${MYSQL_FILE} | awk ‘{print $1}’)
[[ -e "${MD5_FILE}" ]] && MD5_OLD=$(cat ${MD5_FILE}) || MD5_OLD=""

if [[ ${MD5_NEW} != ${MD5_OLD} ]]; then
echo "dn: ${LDAP_GITLAB_USER}" > ${LDAP_FILE}
echo "changetype: modify" >> ${LDAP_FILE}
echo "replace: sshPublicKey" >> ${LDAP_FILE}
while read line;do echo "sshPublicKey: $line" >> ${LDAP_FILE};done < ${MYSQL_FILE}
ldapmodify -d0 -D "${LDAP_USER}" -x -w ${LDAP_PASS} -f ${LDAP_FILE} > /dev/null
echo ${MD5_NEW} > ${MD5_FILE}
fi

rm ${LDAP_FILE}
rm ${MYSQL_FILE}
[/sourcecode]

Posted in howto, Linux | Tagged , , , , , , , , | Leave a comment

Snippets for moving WP mu hosts

This one-liner can be very helpful in case you need to move a running installation of WordPress Multi User to another host. This will fetch the domains, their aliases, reverse the domain name from a.b.c to c.b.a, sort that and finally print it out. With that, you have a nice overview of all FQDNs handled by your WP mu which may help not to miss one.

The first is everything in a readable form, the second is the one-liner.

You will have to set WP_MYSQL_USER, WP_MYSQL_PASSWORD, WP_MYSQL_HOST, and WP_MYSQL_DATABASE according to your specific settings.

[sourcecode language=”shell”]
for entry in $(
mysql -u ${WP_MYSQL_USER} \
–password=${WP_MYSQL_PASSWORD} \
-h ${WP_MYSQL_HOST} \
-s \
-e "SELECT domain FROM ${WP_MYSQL_DATABASE}.wp_domain_mapping;"
)
do
echo $entry | \
awk ‘ \
BEGIN {FS = ".";output_string=""} \
{
if ($3 == "") output_string=$2"."$1 \
else output_string=$3"."$2"."$1
}
END {print output_string}’
done | \
sort
[/sourcecode]

[sourcecode language=”shell”]
for entry in $(mysql -u ${WP_MYSQL_USER} –password=${WP_MYSQL_PASSWORD} -h ${WP_MYSQL_HOST} -s -e "SELECT domain FROM ${WP_MYSQL_DATABASE}.wp_domain_mapping;");do echo $entry | awk ‘BEGIN {FS = ".";output_string=""};{if ($3 == "") output_string=$2"."$1; else output_string=$3"."$2"."$1};END{print output_string}’ ;done | sort
[/sourcecode]

Posted in howto, Linux, Software, Webserver | Tagged , , , , , , , , , , , | Leave a comment

Grab what the _parent won’t give you.

Though IFrames are an evil remnant of the dark age commonly known as the 90s, you still have to deal with them from time to time. Say you want to have a microsite in a YouTube channel. Back in the old days we were not so keen on all the URI parameters but now in the days of Big Data and massive user tracking, we need to know from where a user came. Unfortunately, within an IFrame we have to rely on what the surrounding page is willing to give us.

Luckly, there’s a handy workaround: Work with the referrer’s RequestURI.

Here’s a code snippet for nginx:

[sourcecode language=”shell”]
location / {
set $forward 0;
if ($http_referer ~ http://www.youtube.com/user/your_user/your_channel?(.*)$) {
# take the referrer’s arguments and
# add another to prevent an infinite redirection loop
set $newargs $1&D43ft=42;
set $forward 1;
}

# if this is the redirected call,
# stop nginx from forwarding
if ($arg_D43ft = 42) {set $forward 0;}

if ( $forward = 1) {
# clear the local RequestURI.
# This is necessary to prevent nginx
# from adding the current RequestURI to the redirection
set $args "";
rewrite ^ $scheme://$host$uri$newargs;
}
proxy_pass http://your_target:your_port;
include /etc/nginx/proxy_params;
}
[/sourcecode]

Posted in howto, Linux, Software, Webserver | Tagged , , , , , | Leave a comment

Howto speed-up initial imports to MySQL innodb

Well, it’s an ever hack, however, it works.

  1. Create to databases that differ in the used engine only. One shall use MyISAM, the other InnoDB.
  2. Import everything to the MyISAM database.
  3. connect to mysql and [sourcecode language=”SQL”]INSERT innodb_db.table SELECT * FROM myisam_db.table;[/sourcecode]
Posted in Database | Tagged , , | Leave a comment

nginx, memcached and static files

For some reasons it might make sense to deliver static assets via memcached. As nginx is able to directly talk to memcached, this is even more obvious. But sometimes, there is no backend to put the files into the cache. Therefore, we will have to do it ourselves. Here’s a litte howto, that extends what is written here. I had to extend it as some files were crippled. Therefore, we read the files into a buffer, do some fancy GD operations (mainly not to lose transparency on PNG and GIF) and finally push the buffer into memcached from where nginx takes it.

Nginx expects DOCUMENT_URI as key and the file as value.

First of all, you will need the right nginx config. Like that:
[sourcecode language=”shell”]
# this is just to make sure we deliver the proper content type
location ~* \.jpg$ {
gzip off;
expires max;
# this is to know whether the caching works
add_header x-header-memcached true;
default_type image/jpeg;
#here we define the key
set $memcached_key $uri;
memcached_pass localhost:11211;
memcached_buffer_size 8k;
# cache misses will redirect to this
error_page 404 = @cache_miss;
}

location ~* \.png$ {
gzip off;
expires max;
add_header x-header-memcached true;
default_type image/png;
set $memcached_key $uri;
memcached_pass localhost:11211;
error_page 404 = @cache_miss;
}

location ~* \.gif$ {
gzip off;
expires max;
add_header x-header-memcached true;
default_type image/gif;
set $memcached_key $uri;
memcached_pass localhost:11211;
error_page 404 = @cache_miss;
}
# here is what we do in case a file could not be found
location @cache_miss {
# we need to specify the document root as @cache_miss is a virtual location
root /var/www/www.example.com/htdocs;
# this is just for us so that we know that the delivered file was came from the file system
add_header x-header-memcached false;
}[/sourcecode]
And finally, we need a script that imports all the files into the cache. Like the one below. Important: You will have to run the script in your document root as the final file operations are performed with the mangled file name.
[php]
<?
$mylist=rscandir("/var/www/www.example.com/htdocs"); // where to scan
$srch = array(‘/var/www/www.example.com/htdocs’); // file name mangling
$newval = array(”); //here you could enter something that will be replaced

$memcache = new Memcache;
$memcache->addServer(‘127.0.0.1’);
$memcache->addServer(‘127.0.0.2’); // Add more servers if you like to

// here we recursively scan the given directory and add .jpg, .png and.gif to the file array
function rscandir($base=”, &$data=array()) {
$array = array_diff(scandir($base), array(‘.’, ‘..’));

foreach($array as $value) {
if (is_dir($base."/".$value)) {
$data = rscandir($base."/".$value,$data);

}
elseif (is_file($base."/".$value)) {
$rest = substr($value, -4);
if ((!strcmp($rest,’.jpg’)) || (!strcmp($rest,’.png’)) || (!strcmp($rest,’.gif’)) ) {
$data[] = $base."/".$value;
}
}

}
return $data;
}

while (list($key, $val) = each($mylist)) {
// the URL will be used as key
$url=str_replace($srch,$newval,$val);
// detect the file type from the file’s content
$mime_type = exif_imagetype($val);
if ( $mime_type == 2) { //JPEG
$image=imagecreatefromjpeg($val);
ob_start();
imagejpeg($image);
$output=ob_get_contents();
imagedestroy($image);
ob_end_clean();
$memcache->add($url,$output,false,0);
} elseif ( $mime_type == 3) { //PNG
$image=imagecreatefrompng($val);
imageinterlace($image, true);
imagealphablending($image, true);
imagesavealpha($image, true);
ob_start();
imagepng($image);
$output=ob_get_contents();
imagedestroy($image);
ob_end_clean();
$memcache->add($url,$output,false,0);
} elseif ( $mime_type == 1) { //GIF
$image=imagecreatefromgif($val);
imageinterlace($image, true);
$background = imagecolorallocate($image, 0, 0, 0);
imagecolortransparent($image, $background);
ob_start();
imagegif($image);
$output=ob_get_contents();
imagedestroy($image);
ob_end_clean();
$memcache->add($url,$output,false,0);
}
echo "$val – $mime_type\n";
}
?>
[/php]

Posted in howto, Webserver | Tagged , , , , , | Leave a comment

modify a RequestURI with nginx

Sometimes it is necessary to modify the RequestURI, to strip some GET-pairs. Here is a way how this could be done using nginx. Though we all know that if is evil, it’s sometimes quite handy.
[sourcecode language=”shell”]
# the »Evil Facebook-Like-Hack.«
location / {
# initialize variables with empty values
set $01 "";set $02 "";set $03 "";set $04 "";
set $05 "";set $06 "";set $07 "";set $08 "";

# if GET key exists, copy its value
if ($arg_productName) { set $01 productName=$arg_productName;}
if ($arg_linkId) { set $02 linkId=$arg_linkId;}
if ($arg_target) { set $03 target=$arg_target;}
if ($arg_id) { set $04 id=$arg_id;}
if ($arg_linkValue) { set $05 linkValue=$arg_linkValue;}
if ($arg_groupId) { set $06 groupId=$arg_groupId;}
if ($arg_articleId) { set $07 articleId=$arg_articleId;}
if ($arg_version) { set $08 version=$arg_version;}

# if a GET-key has fb_ in its name then do the funky URL-magic.
if ($args ~* fb_ ) {
# clear the GET-array so that the URI has no GET-pairs
set $args "";
# rewrite the given URL and add the GET-pairs we create above
rewrite ^ $scheme://$host$uri?$01$02$03$04$05$06$07$08 break;
}
}[/sourcecode]
The only drawback is that the URL we receive contains at least a ? for a case when none of the given keys exists – but that’s a minor thing I’d say.

Posted in Linux, Webserver | Tagged , | Leave a comment

find out if your Nginx is really serving the right hosts

Quite I while ago, I posted an article on how to find out whether Apache is still serving the hosts it is configured for. This time, I will show the bash code for doing the same but with nginx.
[sourcecode language=”shell”]
for entry in $(grep -h server_name _config/nginx/* | sed -e ‘s/server_name//g’ -e ‘s/;//g’ -e ‘s/#.*$//g’ -e ‘s/_//g’ );do echo -n $(nslookup "$entry" | grep -A1 Name | grep Address | awk ‘{print $2}’);echo " $entry";done[/sourcecode]

Posted in howto, Linux, Webserver | Tagged , , , , , , , , , , | Leave a comment

Gentoo ebuild: Nginx With Support For Upstream Fair Proxy Load Balancer And HTTP-Auth against LDAP

In a previous article we already presented a modified nginx ebuild containing support for gnosek’s Upstream Fair Proxy Load Balancer. Now, we wanted to have HTTP-Auth against a LDAP server. So we crawled the almighty internet and stumbled over nginx-auth-ldap. Therefore, we updated our last ebuild and extended it with this plugin.

As documentation there is only a small config example. However, anyone who already is  familiar with HTTP-Auth against LDAP with Apache and/or Lighttpd will find this extension pretty straight-forward.

Here you can have a look at the ebuild and there is the SVN checkout path.

The new USE flag is called auth_ldap, gnosek’s plugin can be used with upstream_fair. Add them to your NGINX_MODULES_HTTP in /etc/make.conf

Have a lot of fun!

Posted in howto, Linux, Software, Webserver | Tagged , , , , , , , , | Leave a comment