Skip navigation

Monthly Archives: October 2013

The internet is a bastion of opinion and bullshit. SELinux is a rather difficult bride and as such there is much disinformation regarding how to keep her happy. I have an Apache application that needs to update it’s own cache files and the Fedora installation it was under had the file under the web root with a context of ‘httpd_sys_content_t’. This didn’t work and many of the first suggestions I came across said either disable SELinux or set it to some peculiar context like ‘public_content_rw_t’ and then altering an SELinux boolean to allow such access. We can have no such shenanigans around here, this is how it should be done:

sudo chcon -R -t -P httpd_sys_content_rw_t /var/www/path/to/dir/

UPDATE: There is a new version of this effort.

I needed to modify a local git servers web interface to indicate which revision a remote repo was currently on. This is what happened:

The PHP:

// make sure we have what we need
if( $_SERVER['REQUEST_METHOD'] == 'GET' && !empty($_GET['path'])){

    // our return array
    $return = array();

    // build the git command with the supplied path
    $gitCmd = 'git --git-dir='. $_GET['path'] . '.git --work-tree=' . $_GET['path'] . ' rev-parse HEAD';

    // configure the connection using the local keys
    $connection = ssh2_connect('host.domain.tld', 22, array('hostkey' => 'ssh-rsa'));

    // attempt to authenticate
    if( ssh2_auth_pubkey_file($connection, 'ssh_user', '/path/to/id_rsa.pub', '/path/to/id_rsa') ){

	// capture the return stream, blocking is set to ensure that we have data before we try to read from the stream
	$stream = ssh2_exec($connection, $gitCmd);
	stream_set_blocking($stream, true);

	// $result is the current head revision
	$result = stream_get_contents($stream);

	// make sure we have something and it's not FALSE
	if(!empty($result)){
	    $return['head'] = $result;
	}else{
	    $return['error'] = 'Error retrieving HEAD of remote repository.';
	}
    }else{
	// fail
	$return['error'] = 'SSH Authentication Failed.';
    }

    // send the data back as a json obj
    echo json_encode($return);
}

// done
die();

And the JS:

// update this object with the repos and their paths
var repoObject = {
    'repoName.git' : {
        'path' : '/path/to/local/repo/'
    }
};
// this is our success function
function querySuccess(data){
    // if we have errors, display them
    if( 'error' in data ){
	$('#query_error').text(data.error);
    }else{
        $('.' + data.head).addClass('currentHead');
    }
}
// we run this on document ready for great justice
$(function(){
    var repoTitle = $('#project_name').val();
    // only check rev if we are within a recognized repo
    if (  repoTitle in repoObject) {
        var rData = {
            'path' : repoObject[repoTitle].path
	    };
        $.ajax({
            dataType: 'json',
            url: '/get_head.php',
            data: rData,
            success: function(data){
	        querySuccess(data);
            },
            beforeSend: function(){
                $('#busy_anim').css('display','inline-block');
            },
            complete: function(){
                $('#busy_anim').css('display','none');
            }
        });
    }
});

You are going to want to ensure that you protect the keys you generate to do this, in this example they are in the web directory only protected by Apache.

To restrict a ssh user to connecting from a single IP, add the following to the bottom of the SSHD config. (/etc/sshd/sshd_config)

AllowUsers user1 user2 user3@1.2.3.4

Then bounce the SSH daemon. Done.

Needed to establish an SSH connection to poll another server for the current GIT revision of a repo.

This is an non-standard PECL package, you must compile and install it.

SELinux by default prevents Apache from certain network activity, it is very likely that when trying to use any of the SSH2 methods you will see several denials logged in your SElinux Audit logs. To fix this you will need to allow Apache this access:

sudo setsebool -P httpd_can_network_connect=1