YOURLS is a self-hosted URL shortening service, it is like bit.ly, ur1.ca, goo.gl, is.gd etc.

Official descripton:

YOURLS stands for Your Own URL Shortener. It is a small set of PHP scripts that will allow you to run your own URL shortening service (a la TinyURL or bitly).

Running your own URL shortener is fun, geeky and useful: you own your data and don’t depend on third party services. It’s also a great way to add branding to your short URLs, instead of using the same public URL shortener everyone uses.

We need to install Lighttpd (I already have it since Pi-hole is installed), mysql the LAMP stack.

$ sudo apt install lighttpd mariadb php

Installation instructions are here: https://yourls.org/#Install

Let us start. Download the git repository of YOURLS:

$ cd /var/
$ sudo git clone https://github.com/YOURLS/YOURLS
$ sudo chown -R www-data:www-data YOURLS

We need to copy the user/config-sample.php to user/config.php Edit the user/config.php and set your configurations (explained here: https://yourls.org/#Config)

We will now create the database manually since there are issues with the database (#2307)

$ sudo mysql -uroot

>CRETE DATABASE yourls;
>GRANT ALL PRIVILEGES on `yourls`.* TO 'yourls'@'localhost' IDENTIFIED BY 'MyGoodPassword';
>FLUSH PRIVILEGES;
>\q

 

You can skip this step if you are able to install yourls without error about the database.
Based on issue #2307 we need to manually create the table ‘yourls_url’. Login as yourls and create the table

$ sudo mysql -uyourls -p
>CREATE TABLE IF NOT EXISTS yourls_url (keyword varchar(200) BINARY NOT NULL,url text BINARY NOT NULL,title text CHARACTER SET utf8,timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,ip (keyword), KEY timestamp (timestamp), KEY ip (ip))
->ENGINE=MYISAM;

We need to edit lighttpd configuration (if you are using Pi-hole). The configuration will use http port 82 for yourls (you need to port forward to port 80 in your router, whenever someone is trying to access *.txt files in the url this will deny them access, this is also the equivalent .htaccess apache since lighttpd does not support .htaccess we will use this instead)

$ sudo nano /etc/lighttpd/external.conf
server.tag="nginx"
$SERVER["socket"] == ":82" {
        server.document.root = "/var/YOURLS"
        url.access-deny = ("~", ".md", ".txt", ".json", ".htaccess")
url.rewrite-once = (

    "^/([0-9A-Za-z-]+)?$" => "/yourls-go.php?id=$1",
    "^/([0-9A-Za-z-]+)?\+$" => "/yourls-infos.php?id=$1"

)
}

Edit the user/config.php:


 /* This is a sample config file.
 * Edit this file with your own settings and save it as "config.php"
 * IMPORTANT: edit and save this file as plain ASCII text, using a text editor, for instance TextEdit on Mac OS or
 * Notepad on Windows. Make sure there is no character before the opening <?php at the beginning of this file.
 */

/*
 ** MySQL settings - You can get this info from your web host
 */

/** MySQL database username */
define( 'YOURLS_DB_USER', 'yourls' );

/** MySQL database password */
define( 'YOURLS_DB_PASS', 'MyGoodPassword' );

/** The name of the database for YOURLS */
define( 'YOURLS_DB_NAME', 'yourls' );

/** MySQL hostname.
 ** If using a non standard port, specify it like 'hostname:port', eg. 'localhost:9999' or '127.0.0.1:666' */
define( 'YOURLS_DB_HOST', 'localhost' );

/** MySQL tables prefix */
define( 'YOURLS_DB_PREFIX', 'yourls_' );

/** YOURLS installation URL -- all lowercase and with no trailing slash.
 ** If you define it to "http://sho.rt", don't use "http://www.sho.rt" in your browser (and vice-versa) */

define( 'YOURLS_SITE', 'http://mydomain.mooo.com' );

/** Server timezone GMT offset */
define( 'YOURLS_HOURS_OFFSET', 0 ); 

/** YOURLS language
 ** Change this setting to use a translation file for your language, instead of the default English.
 ** That translation file (a .mo file) must be installed in the user/language directory.
 ** See http://yourls.org/translations for more information */
define( 'YOURLS_LANG', '' ); 

/** Allow multiple short URLs for a same long URL
 ** Set to true to have only one pair of shortURL/longURL (default YOURLS behavior)
 ** Set to false to allow multiple short URLs pointing to the same long URL (bit.ly behavior) */
define( 'YOURLS_UNIQUE_URLS', true );

/** Private means the Admin area will be protected with login/pass as defined below.
 ** Set to false for public usage (eg on a restricted intranet or for test setups)
 ** Read http://yourls.org/privatepublic for more details if you're unsure */
define( 'YOURLS_PRIVATE', true );

/** A random secret hash used to encrypt cookies. You don't have to remember it, make it long and complicated. Hint: copy from http://$
define( 'YOURLS_COOKIEKEY', 'thisisalongrandomsecrethash' );

/** Username(s) and password(s) allowed to access the site. Passwords either in plain text or as encrypted hashes
 ** YOURLS will auto encrypt plain text passwords in this file
 ** Read http://yourls.org/userpassword for more information */
$yourls_user_passwords = array(
        'admin' => 'root'
        // 'username2' => 'password2',
        // You can have one or more 'login'=>'password' lines
        );
/** Debug mode to output some internal information
 ** Default is false for live site. Enable when coding or before submitting a new issue */
define( 'YOURLS_DEBUG', false );

/*
 ** URL Shortening settings
 */

/** URL shortening method: 36 or 62 */
define( 'YOURLS_URL_CONVERT', 36 );
/*
 * 36: generates all lowercase keywords (ie: 13jkm)
 * 62: generates mixed case keywords (ie: 13jKm or 13JKm)
 * Stick to one setting. It's best not to change after you've started creating links.
 */
/** 
* Reserved keywords (so that generated URLs won't match them)
* Define here negative, unwanted or potentially misleading keywords.
*/
$yourls_reserved_URL = array(
        'porn', 'faggot', 'sex', 'nigger', 'fuck', 'cunt', 'dick', 'admin', 'shit'
);

/*
 ** Personal settings would go after here.
 */

define( 'BARRE_LOG_LOGIN_FILENAME', '/var/log/yourls.log' );
define( 'BARRE_LOG_LOGIN_FAILURE', true );

You can enhance your installation by using plugins: https://github.com/YOURLS/awesome-yourls
Securing yourls, we can secure yourls using fail2ban and a recaptcha (if you are planning to make your yourls public access).
The Fail2ban method is done using a plugin, please review the issues since it has a bug.
Follow the steps in their github repo: https://github.com/SweBarre/log-login
https://github.com/SweBarre/log-login/pull/11


$ git clone https://github.com/SweBarre/log-login

For manual configuration of fail2ban using log-login plugin
In the above configuration I already added the define( ‘BARRE_LOG_LOGIN_FILENAME’…


$ sudo apt install fail2ban
$ pear install Log-1.12.7
or use sudo if it has permission errors

Create a new file or edit an existing fail2ban config:

$ sudo nano /etc/fail2ban/jail.d/debian-default.conf
[yourls]
enabled = true
port = http,82
filter  = yourls
logpath = /var/log/yourls.log
maxretry = 12
findtime = 120
logtimezone = UTC

Create a new file:


$ sudo nano /etc/fail2ban/filter.d/yourls.conf
# This is an exempel filter for yourls.
# if you have changed the log format for the plugin
# you must change the filter to match the log format

[Definition]
failregex = .*-  -.*LOGIN FAILURE.*
ignoreregexp =

Create a new file:


$ sudo nano /etc/logrotate.d/yourls 
# change the path to match your log-login settings.

/var/log/yourls.log {
        weekly
        missingok
        rotate 52
        compress
        delaycompress
        notifempty
        create 640 www-data adm
}

For the public interface read these:
https://github.com/YOURLS/YOURLS/wiki/Private-Or-Public
https://github.com/YOURLS/YOURLS/wiki/Public-Shortening

IF YOU WANT TO USE GOOGLE SERVICES TO PROVIDE A CAPTCHA FUNCTION FOLLOW THIS TUTORIAL: (NOTE GOOGLE DOES NOT RESPECT USER PRIVACY SO USE IT IF YOU DO NOT HAVE ANY OTHER CHOICE)
You need to move the file sample-public-front-page.txt to index.php and add the recaptcha code, follow the tutorial below
Read and follow the instructions: http://bitty.link/recaptcha.html
http://blog.yourls.org/2015/05/integrating-the-new-google-recaptcha-with-yourls/

Public Page with recaptcha GOOGLE

An alternative to Google reCaptcha would be securImage (https://www.phpcaptcha.org) it generates captcha and you can easily integrate it in any of your programs. It is licensed under BSD. We will now implement it to our public interface, you need to remove all google recaptcha code, if you implemented it earlier.

Download the source code at :
https://www.phpcaptcha.org/download/
or clone the git site: https://github.com/dapphp/securimage

$ git clone --depth 1 'https://github.com/dapphp/securimage'
Copy the folder to your root website directory (eg. /var/www/)
 $ sudo cp -R securimage /var/www/
 $ sudo chown -R www-data:www-data /var/www/securimage

We now need to edit the public interface file and add the following:

add this below <?php

 session_start();

add the following after the require_once (dirname(__FILE__)…..

include_once $_SERVER['DOCUMENT_ROOT'] . '/securimage/securimage.php';
$securimage = new Securimage();

add below: // Part to be executed if FORM has been submitted

if ($securimage->check($_REQUEST['captcha_code']) == true) {

add below: $status   = isset( $return[‘status’] ) ? $return[‘status’] : ”;

}

add after: echo “<script>init_clipboard();</script>\n”;
}

else { //if url shortening failed it may because of invalid captcha or other
echo "<h2>ERROR: INVALID CAPTCHA OR DUPLICATE URL</h2>";
}

add below: <p><label>Optional title: <input type=”text” class=”text” name=”title” /></label></p>

<img id="captcha" src="/securimage/securimage_show.php" alt="CAPTCHA Image" />
<p><input type="text" name="captcha_code" size="10" maxlength="6" /></p>

Restart lighttpd and try it out.

You need to remove some examples in the secureimage folder if you cloned the git repo otherwise you are ready to go. Enjoy Google-less tracking.

Here is the interface of YOURLS after implementing securimage. This is the basic implementation, I did not include the audio captcha or refresh captcha image.

 

 

Admin page to administer links created from public API

Except where otherwise noted, this work is licensed under Creative Commons Attribution-ShareAlike 4.0 International License (http://creativecommons.org/licenses/by-sa/4.0/).
I hope that this post is useful to you, if you liked this post you may support me via liberapay. Thank you for your support.

Donate using Liberapay