Wallpaper
I have TFT monitor with 1280×1024 resolution and TV connected in nvidia twin view configuration with TV’s resolution of 800×600. Whenever I want to set up a desktop wallpaper on Gnome, I must adjust it, because Gnome “sees” my desktop as one large 2080×1024 desktop. So, I must manually open wallpaper in Gimp and create another picture that contains two wallpaper next to each other, one with 1280×1024 dimension, and another one, with 800×600 dimensions right of the first one. So, I decided that that’s enough. So I utilized imagemagick to accomplish this and put convinient function in my .bashrc file. Here it is:

make_wallpaper(){
    convert -background white "$1" -resize 1280x1024 \( "$1" -resize 800x600 \) +append "$2";
}

Of course, background color isn’t neccesary since it is not visible, I just put it as a reminder. All I have to do now is to call:

make_wallpaper original.png my.png

Sweet, ain’t it;)

, ,

How often do you use power button to shut down your computer? I never use it, and, even if I would have need to shutdown or restart my computer, I would use GUI way to do it (simply because, it is something that is rarely used, I never remember I could use power button in that split second when I want to shut it down)

But, if you (like me) don’t have keyboards with fancy shortcut buttons, why not use that same power button for some shortcut. Or, you can make fun of your Windows friends just by showing what power and mind-boggling functionality Linux have and just waits for yours ideas to unleash it. I think this is great example of that.

I will use Ubuntu to set it up, but, with minor (or even none) modification, this should work on any distro. First you will need, is to remove annoying gnome log-off screen that shows up when you press power button. For this, we will need to change two keys in gconf. Start gconf-editor and change those two keys:

  • /apps/gnome-power-manager/action_button_power
  • /apps/gnome-power-manager/buttons/power

to “nothing” (without quotes). This will disable log-off screen. Now, it’s all about editing /etc/acpi/powerbtn.sh to suit your needs. I will give you two possible scenarios, and there are no limits what you can do.

Enable/disable internet (forwarding)

I already had two little script to enable or disable internet to some users I am routing internet to. These are some iptables stuff (something like `iptables -I FORWARD -p ALL -s 192.168.0.122 -j DROP`) and I had to open console, execute it and later enable it. This can be done with this in /etc/acpi/powerbtn.sh:

#! /bin/sh
if [ -f /var/tmp/internet_off ]; then
    /etc/rc.start_internet
    rm /var/tmp/internet_off
else
    /etc/rc.stop_internet
    touch /var/tmp/internet_off
fi

This is stupid script. It checks for existence of file /var/tmp/internet_off that signalizes if forwarding is on. It then executes appropriate scripts. If you have someone dumb enough, you can tell them that they have no internet because your computer is turned off, and what they see on monitor is just a picture, or drop them a story about virtual (wau!) machine that run even when computer is off (everyone heard of vmware) – something like that:) You can even confirm this by pressing button in front of them to enable or disable their internet access.

Starting firefox

I use firefox all day. If I ever want to dedicate any button to any program, that is certainly firefox. But to start GUI program in shell script that is run as root, we need some workarounds. For example, you need to set DISPLAY and XAUTHORITY environment variable.

#! /bin/sh
export DISPLAY=:0
export XAUTHORITY=/home/your_username/.Xauthority
sudo -u your_username firefox

But, this script have few defects. If firefox is running, it will launch another windows, and we see ‘yourusername’ is all around. This is improved version:

#! /bin/sh
USERNAME=your_username
export DISPLAY=:0
export XAUTHORITY=/home/$USERNAME/.Xauthority
 
if ps -U $USERNAME -u $USERNAME|grep firefox; then
    sudo -u $USERNAME firefox -new-tab about:blank
else
    sudo -u $USERNAME firefox
fi

If firefox is running, it will just open new empty tab, otherwise it will launch it normally. Also, your username is pulled up as variable, so you just need to change second line to your username and this script will work. Have fun!

Further ideas

Only one function for button is nothing. Maybe we can split two different functionality by defining click and double-click on power button. Simple creating file on first click, and checking if file was created 2 seconds before current time (I will not go into details here). Also, you could use that button to open CD tray, why not:) Like anything in Linux, your creativity is your only limit. Do you have any ideas what to do else with this button? What would you put in /etc/acpi/powerbtn.sh?

, , ,

Увод

Пре него што изнесем рецепт, само да кажем да ово није за људе који се не разумеју добро у Линукс, iptables и apache. Да бисте ово извели код своје куће, потребно је да разумете шта радите, не само преписујете јер, у супротном нећете далеко догурати. Овај текст треба да Вам да генералну идеју и да Вас погура у правом правцу, неће урадити све за Вас. Не покушавам да Вас уплашим, само да скренем пажњу да нисам водио много рачуна о детаљима. Такође, ово је текст о Линуксу који ради као рутер и користи iptables и apache, тако да, ако то немате при руци, можете само да читате, али не и да испробате. Наравно, ако сте гуру, вероватно можете постићи сличне резултате и са другим алатима (поред iptables и apache-а), али сте онда сами на своме. Па да кренемо.

КОРИШЋЕЊЕ

Имате Линукс који ради као рутер, и док неким корисницима желите забранити приступ интернету, желите да им прикажете обавештење о о томе. Или желите да забраните приступ одређеним сајтовима, и, уместо жељеног сајта да прикажете Вашу страну са Вашег сервера о томе како корисник није био добар када је ишао на тај и тај сајт, или да је тај сајт забрањен…Свакакве остале идеје које могу одавде да изникну…

ОСНОВНЕ СТВАРИ

ОК, у згради имамо мали сервер који (углавном) служи као рутер за око 20так комшија који деле нет. Сви скупљамо паре и делимо конекцију. Проблем се јавља када неко не жели интернет за следећи месец, или није ту, или заборави да плати…До сада, имали смо просто решење са iptables алатом – REJECT-уј све пакете и дозволи да прођу само пакети са ИП адреса које су платиле за интернет, које би изгледало некако овако:

iptables -I FORWARD -i ext0 -o ext1 -j DROP
iptables -I FORWARD -p ALL -s 192.168.0.XX -j ACCEPT
iptables -I FORWARD -p ALL -d 192.168.0.XX -j ACCEPT

Онда смо комшија и ја дошли на идеју да онај ко није платио за интернет, када посети неки страну, добије страну на којој пише да није платио и сл. До сада му се интернет прегледач куцао при разрешавању ИП адресе хоста (јер ни DNS пакети нису могли да прођу).

Прва идеја која нам је пала на памет је хаковање нашег DNS сервера, али, иако универзално, ово решење је много зајебано за урадити, није проширљиво, тешко се мења и углавном…срање, тако да сам се одлучио за ово друго, изузетно ефикасно решење изложено даље.

Основна идеја је преусмерити све ХТТП захтеве од корисника који нису платили ка нашем серверу и приказати им једноставну страну обавештења. Решење се може поделити на два дела: део са iptables-има и део са apache-ом. Прво нам треба iptables део.

IPTABLES ДЕО

Проста линија која преусмерава одређеног корисника би била:

iptables -t nat -I PREROUTING -s 192.168.0.XX -p tcp --dport 80 -j REDIRECT --to-ports 3001

Објашњење на брзину је да се сви TCP пакети корисника са ИП адресом 192.168.0.XX који су намењени за порт 80 преусмеравају на порт 3001 нашег сервера. Ту ћемо ставити да наш сервер слуша. Овај, чек мало…па ово не ради! Зашто? Просто, када корисник затражи неку страну, на пример http://www.mozilla.com/en-US/firefox, прво треба разрешити ИП адресу, па се тек онда конектовати, тј. пре него што је иједан пакет за порт 80 послат, прво корисник шаље и прима пакете ка DNS серверу. А, ако имамо (као што је горе написано):

iptables -I FORWARD -i ext0 -o ext1 -j DROP

име хоста не може бити разрешено, па неће бити ни HTTP пакета. Дакле, морамо дозволити DNS пакете тамо и овамо са нечим оваквим:

iptables -I FORWARD -s 192.168.0.XX -p udp --dport 53 -j ACCEPT
iptables -I FORWARD -d 192.168.0.XX -p udp --sport 53 -j ACCEPT
iptables -t nat -I PREROUTING -s 192.168.0.XX -p tcp --dport 80 -j REDIRECT --to-ports 3001

Ово је у неку руку trade-off (српски речено: буџење) јер сада наш корисник није комплетно изолован од интернета – има приступ DNS серверима. ОК, први део са преусмеравањем је готов, сада да наместимо apache.

APACHE ДЕО

Све што треба урадити је направити нови виртуелни хост на apache-у. Иако је наша конфигурација жестоко измењена у односу на конфигурацију по инсталацији, све је било јако просто. Можда код Вас овај рецепт неће радити, али додавање следећих линија на крај httpd.conf-а је све што је било потребно:

Listen 192.168.0.1:3001
Listen 127.0.0.1:3001
NameVirtualHost *:3001
 
    ServerName 
    DocumentRoot /var/www/no_net/
    RewriteEngine On
    RewriteRule   ^.* /index.html

Када сте додали ово на крај, сада само направите нови htdocs корени директоријум (овде је /var/www/no_net/) са index.html-ом који ће садржати обавештење које ћемо приказати корисницима који нису платили интернет. Порт на коме ће овај виртуелни хост слушати (3001) је исти као онај дефинисан код iptables дела. Као што видите, Listen директива је само за localhost и за наш ЛАН, тако да хост није видљив са интернета. Ако погледате пажљиво у VirtualHost директиву, примећите две чудне линије:

RewriteEngine On
RewriteRule   ^.* /index.html

Ове линије раде замену свега у УРЛ-у са “/index.html”. Зашто? Па, хајде да претпоставимо да је наш корисник хтео да оде на сајт http://www.mozilla.com/en-US/firefox/. После тога се преусмерава на порт 3001. Одатле, корисников интернет прегледач тражи /en-US/firefox/ страну која, наравно, не постоји код нас. Најједноставније решење овог проблема је са apache-овим mod_rewrite модулом који ће замењивати све GET захтеве. Друга линија ради управо то – уз помоћ регуларних израза, замењује било шта са “/index.html”. Све што Вам је сада преостало да урадите је да направите фину index.html страну и то је то.

Али, чекај, ово је много просто да би било (geek) фенси. Зато ћемо да зачинимо сад мало са мало Bash магије.

НАПРЕДНЕ СТВАРИ

Пошто је наша мрежа на подмрежи 192.168.0.0/24, имамо 253 могућих ИП адреса и око 20 корисника. Генерално, у скрипти за подешавање iptables-а ћемо морати да поновимо 253-20 пута део:

iptables -I FORWARD -s 192.168.0.XX -p udp --dport 53 -j ACCEPT
iptables -I FORWARD -d 192.168.0.XX -p udp --sport 53 -j ACCEPT
iptables -t nat -I PREROUTING -s 192.168.0.XX -p tcp --dport 80 -j REDIRECT --to-ports 3001

и 20 пута део:

iptables -I FORWARD -p ALL -s 192.168.0.XX -j ACCEPT
iptables -I FORWARD -p ALL -d 192.168.0.XX -j ACCEPT

Хух…Или да унајмимо црнца или да научимо Bash.
Дакле, ево како сам то извео. Ово није никакво елеганци решење, али ће Вам дати идеју. Направите фајл /etc/allowed_ips и, у њему, ставите последње октете ИП адреса које имају интернет – један октет по линији. Дакле, ако 192.168.0.12 и 192.168.0.34 имају интернет, овај фајл би изгледао овако некако:

1
12
34

Наша подмрежа има фиксне адресе, и због једноставности, не пишемо целу ИП адресу (зато само последњи октет). Такође, приметите да је у овом фајлу наведен и сâм сервер (који има адресу 192.168.0.1). Сада, направите скрипту ip_allowing (ставите је где год Вам је згодно) са следећим садржајем:

#!/bin/bash
 
FILE=/etc/allowed_ips
ip_listing=`cat $FILE`
 
function check_exist {
    for i in $ip_listing; do
        if [ ${i:0:1} != "#" ]; then
            if [ "$i" = "$1" ]; then
                return 1
            fi
        fi
    done
    return 0
}
 
for ip in `seq 1 254`; do
    check_exist $ip
    if [ $? -eq 1 ]; then
        #ip exist
        iptables -I FORWARD -p ALL -s 192.168.0.$ip -j ACCEPT
        iptables -I FORWARD -p ALL -d 192.168.0.$ip -j ACCEPT
        echo allowing 192.168.0.$ip
    else
        #ip doesn't exist
        iptables -I FORWARD -s 192.168.0.$ip -p udp --dport 53 -j ACCEPT
        iptables -I FORWARD -d 192.168.0.$ip -p udp --sport 53 -j ACCEPT iptables -t nat -I PREROUTING -s 192.168.0.$ip -p tcp --dport 80 -j REDIRECT --to-ports 3001
    fi
done

Нема овде никакве вуду магије. Функција check_exist узима број (последњи октет) као први аргумент и проверава да је треба пустити ту ИП адресу и враћа 1 ако је у листингу, 0 ако није. Главни део иде у петљи од 1 до 254 и, или дозвољава приступ DNS серверима и ради преусмеравање, или дозвољава све пакете. Ако сте загледали, можда сте приметили линију:

if [ ${i:0:1} != "#" ]; then

Овом линијом смо дозволили да имамо (нешто што личи на) коментаре у нашем /etc/allowed_ips фајлу и да их игноришемо, тако да овај фајл сад може изгледати нпр. овако:

#server
1
#pera
12
#zika
34

Згодно, зар не. Све што нам је сада остало је да позовемо нашу скрипту (и да јој дамо exec привилегије, али то знате, иначе не бисте читали довде) одакле год да подешавате Ваше iptables-е. Пример би био:

iptables -I FORWARD -i ext0 -o ext1 -j DROP
/etc/rc.d/ip_allowing

Шта даље?

Као прво, ово је просто решење. Има две мане, а то су: корисници имају приступ DNS серверу и друга, ако корисник затражи непостојећу адресу (нпр. www.blabla-tucmuc-nemaovog.com), добиће страну у интернет прегледачу да она не постоји, тј. наше обавештење ће добити само ако је разрешавање успело. Ово су ситнице преко којих ја могу да прођем, а ако Ви не можете – решење лежи у подешавању DNS сервиса на серверу.
Осим ових мана, има много ствари које се могу унапредити. На пример, можда желите да забрањујете кориснике по MAC адреси, не по ИП адресама. Или, ако имате већу subnet маску, ово може бити споро, па треба размислити о томе да Ваше iptables команде раде са ИП опсезима. Или, можда желите да вучете дозвољене ИП адресе из неког другог извора, нпр. LDAP-а или MySQL-а, а не из фајла. Такође, уз избацивање одређених ствари, можете преусмерити кориснике само када траже одређени сајт, тако што би се у iptables команди користила и одредишна ИП адреса (-d), не само изворна. Што се тиче apache дела, приметите да је rewrite директива код виртуелног хоста гладна, тј. гута све и замењује у једну ствар. Ово нам не дозвољава да имамо више страна на том хосту. Ако бисте желели да имате две стране (на пример, index.html и contact.html), морали бисте да се играте са регуларним изразима и да замењујете било шта осим “/contact.html” у /index.html.

Могућности су неограничене. као и са свим у вези Линукса. Само треба да знате шта хоћете и како да то урадите – simple as that.

, , , , ,

KDE and Cyrillic filenames

I just found out what I have been looking for a long time now – how to setup KDE to show Cyrillic filenames on ext2/ext3 partitions. As I later found out (in hard way) it has nothing to do with filesystem itself, e.g. ext2/ext3 partitions support UTF-8 – problem was in KDE (e.g. Linux) setup. One has to set locale, e.g. just put these few lines in your profile.d (at my slack it is in /etc/profile.d/), make new script in it and type this:

#!/bin/sh
 
LANG=en_US.UTF-8
LANGUAGE=$LANG
LC_ALL=$LANG
 
export LC_ALL LANGUAGE LANG

Although my KDE is in Cyrillic and my locale should be Serbian (sr_CS.UTF-8), I still used en_US (it doesn’t matter for KDE, it uses its own locale setup, this is only for terminal locale), the thing that matter in this script is that you should tell every program that you use UTF-8. Just login again and try to rename any file – it should be working now.

Although my KDE is in Cyrillic and my locale should be Serbian (sr_CS.UTF-8), I still used en_US (it doesn’t matter for KDE, it uses its own locale setup, this is only for terminal locale), the thing that matter in this script is that you should tell every program that you use UTF-8. Just login again and try to rename any file – it should be working now.
, ,