Skip navigation

Category Archives: Linux

As a general rule, file systems degrade in performance as they become populated. This especially holds true for random reads within a single directory. I like to call this, The Irrevocable Solution. Delete all files within a directory older than 1 day.

Within the target directory:

sudo find . -type f -mtime +1 -exec rm -f {} +

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

Ran into this during an upgrade of a personal media server upgrade. I have a user who requires a low bandwidth stream for her music, as some of her library is in flac this becomes problematic. Previously I had used the flac library in conjunction with lame to transcode the flac file to mp3 upon request, cached it locally during the push and then discard the data. Now I’m using ffmpeg, which uses many of the same libraries though makes configuration easier. On Fedora however, one of the SELinux contexts on a child library in incorrect, causing Ampache to report:

ffmpeg: error while loading shared libraries: /lib/swresample.so.0: cannot restore segment prot after reloc: Permission Denied

That just smelled like an SElinux denial, so a little research led me to a solution -a very similar solution I had come to during an mySQL compile last week, so I’m writing this one down.

sudo chcon -t textrel_shlib_t /lib/swresample.so.0

Fixed. This should be rolled into a policy so that it survives a re-label.

I need to be able to relay mail over SMTP from a sendmail instance on Fedora, through Google Mail servers. This is how I did it.

(Make sure you have the m4, sendmail, and sendmail-cf package installed.)

In the client auth config (/etc/mail/auth/client-info):

AuthInfo:smtp.gmail.com "U:root" "I:myusername@gmail.com" "P:password" "M:PLAIN"
AuthInfo:smtp.gmail.com:587 "U:root" "I:myusername@gmail.com" "P:password" "M:PLAIN"

Create the client info database file:

sudo makemap -r hash client-info.db
sudo chmod 600 /etc/mail/auth/client-info
sudo chmod 600 /etc/mail/auth/client-info.db

UPDATE: The above stopped working for me as of Fedora 19, the following is what I had to use to update the client-info.db:

cd /etc/mail/auth
sudo makemap -v hash client-info.db < client-info
sudo chmod 600 /etc/mail/auth/client-info
sudo chmod 600 /etc/mail/auth/client-info.db

The M4 configuration:

Feature	FEATURE(`authinfo',`hash /etc/mail/auth/client-info.db')dnl	
Define	define(`SMART_HOST',`smtp.gmail.com')dnl	
Define	define(`RELAY_MAILER_ARGS', `TCP $h 587')dnl	
Define	define(`ESMTP_MAILER_ARGS', `TCP $h 587')dnl	
Define	define(`CERT_DIR', `/etc/mail/ssl')dnl	
Define	define(`confCACERT_PATH', `CERT_DIR')dnl	
Define	define(`confCACERT', `CERT_DIR/ca-bundle.crt')dnl	
Define	define(`confCRL', `CERT_DIR/ca-bundle.crt')dnl	
Define	define(`confSERVER_CERT', `CERT_DIR/sendmail.pem')dnl	
Define	define(`confSERVER_KEY', `CERT_DIR/sendmail.pem')dnl	
Define	define(`confCLIENT_CERT', `CERT_DIR/sendmail.pem')dnl	
Define	define(`confCLIENT_KEY', `CERT_DIR/sendmail.pem')dnl	
Define	define(`confAUTH_MECHANISMS', `EXTERNAL GSSAPI DIGEST-MD5 CRAM-MD5 LOGIN PLAIN') TRUST_AUTH_MECH(`EXTERNAL DIGEST-MD5 CRAM-MD5 LOGIN PLAIN')dnl

Rebuild the config:

m4 sendmail.mc > sendmail.cf

If you run into SELinux denials, check your sendmail flags with:
sestatus -b | grep -i sendmail
If you see 'http_can_sendmail' is off, issue setsebool -P httpd_can_sendmail 1