, ,

11 июня, 2025

Создание приложения при помощи Node js для Mac OS

Хотел бы показать как достаточно просто создавать Desktop приложения node js на базе библиотеки Electron.

Electron по своей сути это движок браузера — chromium, при помощи которого можно создавать приложения на основе веб сайта или веб сервис, достаточно всего лишь указать url сайта который должен открываться внутри хромиума и собрать приложение под нужную систему.

Тут я продемонстрирую как это сделать для mac os на процессоре arm, но в любой другой системе алгоритм создания приложения будет таким же.

Для демонстрации создания приложения, я выбрал видео сервис Youtube, который будет работать как десктоп приложение mac os. Приложение будет инсталироваться стандартным образом ( через dmg установщик ) особенностью данного приложения будет то что youtube будет запускаться через защищенный канал shadowsock, который можно настроить по инструкции тут

Для начала необходимо установить требуемые пакеты для начала разработки

brew install node
brew install npm
mkdir youtube-sock
cd youtube-sock
npm init -y
npm install electron
npm install -g electron-packager
npm install electron --save-dev
npm install dotenv
npm install electron-installer-dmg -g

После того как node js и electron установлены можно приступить к разработке кода приложения

vim index.js

И вот сам код прилаги

require('dotenv').config(); // Загружаем .env
const { app, BrowserWindow, Menu } = require('electron');
const path = require('path');

// Получаем прокси из .env или используем значение по умолчанию
const proxyUrl = process.env.PROXY_URL || 'socks5://127.0.0.1:1080';

// Применяем настройки прокси
app.commandLine.appendSwitch('proxy-server', proxyUrl);

function createWindow() {

  // создаем окно, тут можно задать параметры, например отмеить devtools и задать полноэкранный режим при запуске, задать иконку приложения
  const win = new BrowserWindow({
    width: 1200,
    height: 800,
    icon: path.join(__dirname, 'icon.icns'),
    webPreferences: {
      devTools: false
    }
  });

  // Задаем URL который должен подгружатся в наш Chromium
  win.loadURL('https://youtube.com');

  // Запрет на переход на сторонние ресурсы
  win.webContents.on('will-navigate', (event, url) => {
    if (!url.includes('youtube.com')) {
      event.preventDefault();
      win.loadURL('https://youtube.com');
    }
  });

  // Запрет на открытие других ресурсов кроме youtube.com
  win.webContents.setWindowOpenHandler(({ url }) => {
    if (!url.includes('youtube.com')) {
      return { action: 'deny' };
    }
    return { action: 'allow' };
  });

  // убираем системное стандартное меню
  Menu.setApplicationMenu(null);
}

// Запускаем приложение
app.whenReady().then(createWindow);

Как видно код очень простой и не требуется каких-то серьезных знаний для того чтобы разобраться что он делает, но комментарии я оставил

Теперь нужно собрать пакет установки для нужной системы

Для начала нужно добавить иконку приложения, для этого можно взять картинку ( будущую иконку приложения ) в формате png и конвертировать ее в специальный формат для приложений mac os — incs ( для других систем это будет другой формат иконок, например ico )

Конвертировать картинку из png в incs можно встроенной командой mac os

sips -s format icns icon.png --out icon.icns

Картинка готова! Далее нужно не забыть создать .env файл с одной единственной настройкой — вашим proxy ( sock )

echo 'PROXY_URL=socks5://127.0.0.1:1080' > .env

вместо socks5://127.0.0.1:1080 укажите свой proxy

Проверяем запуск

npx electron .

Если окошко появилось и в нем запустился Youtube то можно приступать к сборки бинарника для вашей архитектуры.

electron-packager . "YouTube Sock" --platform=darwin --arch=arm64 --icon=icon.icns

Тут я указал название приложения, указал в качестве платформы darwin ( mac os ) в качестве архитектуры указал архитектуру своего нотпада — arm64

После успешной данной операции уже можно спокойно перетащить готовый app файл из новой директории «YouTube Sock-darwin-arm64» в директорию Applications и запускать полноценное приложение в своей системе, но если хотите создать dmg и поделится готовой сборкой с кем-нибудь то можно еще выполнить вот это

electron-installer-dmg YouTube\ Sock-darwin-arm64/YouTube\ Sock.app "Youtube-Sock" 

После этого в директории появится файл Youtube-Sock.dmg и из него можно установить программу на другой мак на архитектуре arm64 :)

На этом все, посмотреть весь код и забрать себе можно тут

Если есть вопросы, пишите сюда и подписывайтесь на обновления сайта тут

, , , ,

10 июня, 2025

Скрипт запуска vpn для mac os и не только

Привет! В Mac OS чаще всего используют программу Tunnelblick для подключения по vpn. Я тоже ей пользовался и это было отвратительно, может у меня кривые руки и я не сумел ее грамотно настроить ( ну те проставить правильно галочки в gui интерефейсе ), но в целом получить от нее стабильности и простоты у меня так и не получилось.

Возможно эта программное обеспечение для подключения к vpn удобно когда тебе нужно подключать по 1 vpn для просмотра ютубчика на обеде ( хотя vpn для этого не нужен, достаточно настроить анонимный proxy ) но когда требуется что-то более сложное Tunnelblick начинает хромать.

Стандартная ситуация, вы работаете в крупной компании и вам требуется использовать корпоративные сервисы, которые развернуты внутри сети. Для этой цели вам выдали vpn.

Так же внутри компании есть разные отделы, например завязанные на какие-то конкретные проекты и внутри корпоративной сети у вас должен так же быть отдельный доступ к внутренним сервисам вашего отдела проекта в котором вы работаете, таким образом вам уже требуется подключаться к 2 vpn сетям одновременно приплюсуем к этому что вы живете в стране в которой часть ресурсов заблокирована из-за непростой геополитической ситуации и вам уже потребуется 3 vpn которые должны работать и не конфликтовать друг с другом.

Tunnelblick с 3 VPN уже работает плохо, давайте еще добавим, что VPN тоже не работает стабильно так как время от времени провайдер тестирует оборудование фильтрации VPN и связь пропадает. Это катастрофа, если вам требуется VPN для работы.

Допустим, еще в вашей компании время от времени обновляются ovpn и его нужно скачивать по специальной ссылке и таким образом, используя гуи приложения для vpn вам придется время от времени заниматься удалением, добавлением и если вы используете еще sock5 для своего подключения — правками ovpn файлов.

Каждый раз после того как Tunnelblick зависал, я грустил и вспоминал времена когда у меня был arch linux и для подключения к vpn я использовал простой скрипт на bash.

Последней каплей стала ситуация когда после обновления ОС, вместе с зависанием Tunnelblick стала пропадать сеть так что требовалась перезагрузка макбука для того чтобы сеть снова появилась ( позже я разобрался с этим и это оказалось, что это из-за того что Tunnelblick не мог правильно возвращал DNS сервера на место ). Это стало последней каплей терпения и я решил окончательно решить этот вопрос и удалив с радостью Tunnelblick написал свой скрипт для подключения к VPN, чем хочу поделится тут.

#!/bin/bash

VPN_PID="$HOME/.vpn/vpn.pid"
LOG_FILE="$HOME/.vpn/vpn_download.log"

# в этом файле нужно прописать ссылки ( каждая на своей строке по которым скрипт будет забирать обновленные ovpn файлы
# содержимое файла ~/.vpn/update.txt должно иметь вот такой вид: 
# https://corporate.site/share/project.ovpn
# https://corporate.size/share/corporate.ovpn
URL_LIST_FILE="$HOME/.vpn/update.txt"

# пути к .ovpn файлам 
TARGET_DIR="$HOME/.vpn/configs"
VPN_CONFIG_1="$TARGET_DIR/corporate.ovpn"
VPN_CONFIG_2="$TARGET_DIR/project.ovpn"
VPN_CONFIG_3="$TARGET_DIR/private.ovpn"

# логин и пароль от корпоративного VPN
# содержимое файла ~/.vpn/password.auth
# <login_vpn>
# <password_vpn> 
VPN_PASSWORD="$HOME/.vpn/password.auth"

# пусть к команде openvpn
# в моем случае я ставил openvpn для mac os через homebrew
VPN_COMMAND="/opt/homebrew/sbin/openvpn"

# замените на ваш DNS
DNS_SERVER="8.8.8.8"

# замените на вашу сеть
NETWORK_SERVICE="Wi-Fi"

# таймауты и настройки проверки подключений к vpn
CHECK_TIMEOUT=10
MAX_ATTEMPTS=3
CONNECT_TIMEOUT=30

# Shadowsocks параметры, как настраивать я писал тут: 
# Как настроить Shadowsocks - https://killercoder.ru/maskirovka-trafika-cherez-shadowsocks
# Как установить Shadowsocks - https://killercoder.ru/ustanavlivaem-shadowsocks-na-svoj-server
SHADOWSOCKS=false
SHADOWSOCKS_PROXY="socks5://127.0.0.1:1080"

# Парсинг аргументов
# Поддерживает 1 аргумент --sock ( подключение через sock proxy )
while [[ $# -gt 0 ]]; do
    case "$1" in
        --sock)
            SHADOWSOCKS=true
            shift
            ;;
        *)
            break
            ;;
    esac
done

# загружает обновленные файлы ovpn с поддержкой загрузки через sock5 ( если дела совсем плохи.. )
download_file() {
    local url=$1
    local filename=$(basename "$url")
    local target_path="$TARGET_DIR/$filename"
    local retry=0
    
    echo "$(date '+%Y-%m-%d %H:%M:%S') - Начало загрузки $filename" >> "$LOG_FILE"
    
    while [ $retry -lt $MAX_ATTEMPTS ]; do
        if [ "$SHADOWSOCKS" = true ]; then
            if curl -sSL --fail --connect-timeout $CONNECT_TIMEOUT --proxy "$SHADOWSOCKS_PROXY" "$url" -o "$target_path"; then
                echo "$(date '+%Y-%m-%d %H:%M:%S') - Успешно (через Shadowsocks): $filename сохранен в $target_path" >> "$LOG_FILE"
                echo "✅ $filename успешно загружен через Shadowsocks"
                return 0
            fi
        else
            if curl -sSL --fail --connect-timeout $CONNECT_TIMEOUT "$url" -o "$target_path"; then
                echo "$(date '+%Y-%m-%d %H:%M:%S') - Успешно: $filename сохранен в $target_path" >> "$LOG_FILE"
                echo "✅ $filename успешно загружен"
                return 0
            fi
        fi
        
        ((retry++))
        echo "$(date '+%Y-%m-%d %H:%M:%S') - Попытка $retry/$MAX_ATTEMPTS: Ошибка загрузки $filename" >> "$LOG_FILE"
        sleep 2
    done
    
    echo "$(date '+%Y-%m-%d %H:%M:%S') - Ошибка: не удалось загрузить $filename после $MAX_ATTEMPTS попыток" >> "$LOG_FILE"
    echo "❌ Не удалось загрузить $filename после $MAX_ATTEMPTS попыток"
    return 1
}

update() {

    if [ ! -f "$URL_LIST_FILE" ]; then
        echo "❌ Файл $URL_LIST_FILE не найден!" | tee -a "$LOG_FILE"
        exit 1
    fi

    stop_vpn
    sleep 2
    echo "=== Начало загрузки VPN-конфигов ===" | tee -a "$LOG_FILE"
    echo "Чтение URL из файла: $URL_LIST_FILE" | tee -a "$LOG_FILE"

    success_count=0
    fail_count=0

    while IFS= read -r url || [ -n "$url" ]; do
        if [[ -z "$url" || "$url" == \#* ]]; then
            continue
        fi
    
        download_file "$url"
        if [ $? -eq 0 ]; then
            ((success_count++))
        else
            ((fail_count++))
        fi
    done < "$URL_LIST_FILE"

    echo "=== Загрузка завершена ===" | tee -a "$LOG_FILE"
    echo "Успешно: $success_count файлов" | tee -a "$LOG_FILE"
    echo "Не удалось: $fail_count файлов" | tee -a "$LOG_FILE"

    if [ $fail_count -gt 0 ]; then
        exit 1
    else
        start_vpn       
        exit 0
    fi
}

# команда запуска личного VPN 
start_private() {
    stop_vpn
    sleep 2
    echo "🔒 Запускаю VPN private..."
    
    if [ "$SHADOWSOCKS" = true ]; then
        echo "Использую Shadowsocks proxy для подключения"
        sudo $VPN_COMMAND \
            --config "$VPN_CONFIG_3" \
            --socks-proxy 127.0.0.1 1080 \
            --log-append /var/log/openvpn.log &
	ALL_PROXY=$SHADOWSOCKS_PROXY
    else
        sudo $VPN_COMMAND \
            --config "$VPN_CONFIG_3" \
            --log-append /var/log/openvpn.log &
    fi
    
    echo "VPN(private)" > $VPN_PID
}

# команда запуска корпоративного VPN
start_vpn() {
    stop_vpn  
    echo "🔒 Запускаю VPN corporate..."

    # Проверка наличия нужных файлов
    if [[ ! -f "$VPN_CONFIG_1" ]]; then
        echo "❌ Ошибка: файл конфигурации $VPN_CONFIG_1 не найден!"
        exit 1
    fi

    if [[ ! -f "$VPN_CONFIG_2" ]]; then
        echo "❌ Ошибка: файл конфигурации $VPN_CONFIG_2 не найден!"
        exit 1
    fi

    if [[ ! -f "$VPN_PASSWORD" ]]; then
        echo "❌ Ошибка: файл аутентификации $VPN_PASSWORD не найден!"
        exit 1
    fi

    if [ "$SHADOWSOCKS" = true ]; then
        echo "Использую Shadowsocks proxy для подключения"
        sudo $VPN_COMMAND \
            --config "$VPN_CONFIG_1" \
            --auth-user-pass "$VPN_PASSWORD" \
            --socks-proxy 127.0.0.1 1080 \
            --log-append /var/log/openvpn.log &

        sudo $VPN_COMMAND \
            --config "$VPN_CONFIG_2" \
            --auth-user-pass "$VPN_PASSWORD" \
            --socks-proxy 127.0.0.1 1080 \
            --log-append /var/log/openvpn.log &
    else
        sudo $VPN_COMMAND \
            --config "$VPN_CONFIG_1" \
            --auth-user-pass "$VPN_PASSWORD" \
            --log-append /var/log/openvpn.log &

        sudo $VPN_COMMAND \
            --config "$VPN_CONFIG_2" \
            --auth-user-pass "$VPN_PASSWORD" \
            --log-append /var/log/openvpn.log &
    fi

    # тут же проверяем подключение
    attempt=1
    while [ $attempt -le $MAX_ATTEMPTS ]; do
        echo "Проверка подключения (попытка $attempt/$MAX_ATTEMPTS)..."
    
        if check_vpn_connection; then
            echo "VPN успешно подключен!"
        
            if set_dns; then
                export CURRENT_VPN="work"
                echo "VPN(corporate)" > $VPN_PID
                exit 0
            else
                exit 1
            fi
        fi
    
        sleep $CHECK_TIMEOUT
        ((attempt++))
    done
}

stop_vpn() {
    echo "🛑 Останавливаю VPN..."
    sudo networksetup -setdnsservers $NETWORK_SERVICE empty
    sudo pkill -SIGINT openvpn
    rm -f $VPN_PID
}

log() {
    sudo tail -f /var/log/openvpn.log
}

empty_dns() {
    sudo networksetup -setdnsservers $NETWORK_SERVICE empty
}

status_vpn() {
    if pgrep -x "openvpn" > /dev/null; then
        echo "✅ VPN работает (PID: $(pgrep -x "openvpn"))."
        if [ -f "$VPN_PID" ]; then
            echo "Текущий профиль: $(cat "$VPN_PID")"
        fi
        if [ "$SHADOWSOCKS" = true ]; then
            echo "Используется Shadowsocks proxy"
        fi
    else
        echo "❌ VPN не запущен."
    fi
}

clear_utun() {
    for i in $(ifconfig | grep '^utun' | cut -d: -f1); do
        if ! lsof -i | grep -q "$i"; then
            echo "Удаляю $i..."
            sudo ifconfig "$i" down
            sudo ifconfig "$i" destroy
        fi
    done
}

# функция остановки DNS
set_dns() {
    echo "Устанавливаю DNS $DNS_SERVER для $NETWORK_SERVICE..."
    sudo networksetup -setdnsservers "$NETWORK_SERVICE" "$DNS_SERVER"
    
    if networksetup -getdnsservers "$NETWORK_SERVICE" | grep -q "$DNS_SERVER"; then
        echo "DNS успешно изменён"
        return 0
    else
        echo "Ошибка: не удалось изменить DNS"
        return 1
    fi
}

# функция проверки соединения
check_vpn_connection() {
    if ifconfig | grep -q '^utun\|^tun'; then
        if ping -c 1 -t 2 10.34.96.1 >/dev/null 2>&1; then
            return 0
        fi
    fi
    return 1
}

case "$1" in
    corp)
        start_vpn
        ;;
    stop)
        stop_vpn
        ;;
    restart)
        stop_vpn
        sleep 2
        start_vpn
        ;;
    status)
        status_vpn
        ;;
    private)
        start_private
        ;;
    empty_dns)
        empty_dns
        ;;
    log)
        log
        ;;
    clear_utun)
        clear_utun
        ;;
    update)
        update
        ;;
    *)
        echo "Использование: $0 {start|stop|restart|status|update|clear_utun|empty_dns|log} [--sock]"
        echo ""
        echo "Опции:"
        echo "  --sock    Использовать Shadowsocks proxy для подключения"
        exit 1
esac

Все подробности как что работает есть в комментариях в коде

Есть еще несколько вещей, которые можно сделать для удобства. Например, чтобы каждый раз не вводить пароль при запросе sudo через visudo добавляете

user ALL=(ALL) NOPASSWD: /opt/homebrew/sbin/openvpn
user ALL=(ALL) NOPASSWD: /usr/sbin/networksetup
user ALL=(ALL) NOPASSWD: /opt/homebrew/sbin/openvpn
user ALL=(ALL) NOPASSWD: /opt/homebrew/sbin/openvpn
user ALL=(ALL) NOPASSWD: /usr/sbin/networksetup
user ALL=(ALL) NOPASSWD: /usr/bin/pkill -SIGINT openvpn

Вместо user указываете своего пользователя, вместо команд правильные пути в вашей системе. Правильный путь можно узнать командой:

$ which openvpn

И так же по-аналогии с sock5 можно сделать вывод подключения в командной строке, если пользуетесь оболочкой zsh

vpn_status() {
  if [[ -f ~/.vpn/vpn.pid ]]; then
    local vpn_name=$(cat ~/.vpn/vpn.pid)
    echo "🟢 VPN: %F{green}$vpn_name%f"  # Иконка + название VPN
  else
    echo "🔴 VPN: %F{red}DISCONECT%f"
  fi
}

PROMPT='
... %F{yellow}%f $(vpn_status) ...

На этом все.. Если есть вопросы, пишите в телегу а так же подписывайтесь на обновление сайта в группу телеграм

, , ,

29 мая, 2025

Маскировка трафика через Shadowsocks

В предыдущем посте, я описывал, что такое shadowsock и как он позволяет поднять зашифрованый канал связи через локальный прокси. В этой статье, я хочу поделится способом как можно замаскировать трафик shadowsock используя плагин v2ray. Подобная маскировка может быть полезной когда требуется обойти фильтры провайдера которые фильтруют трафик используя сложные алгоритмы DPI — глубокого анализа данных, что позволяет фильтрующим системам резать запросы отправленные через VPN или TOR, shadowsocks и плагин v2ray вполне могут решить эту проблему.

! Важное дополнение. Данный материал приводится исключительно в образовательных и исследовательских целях. Не в коем случае не повторяйте это в реальности, если подобное запрещено законодательством страны в которой вы живете !

Что потребуется для настройки:

  • Отдельный хостинг, можете попробовать, например, вот этот
  • Локальный компьютер с Mac OS ( но на любой машине c *nix тоже заработает с минимальными изменениями )

Первое что потребуется сделать, это установка shadowsock о которой можно почитать тут — Устанавливаем Shadowsocks на свой сервер

Сразу же после того как вы установили shadownsock обезательно настройти фаервол сервера, чтобы он не блокировал трафик shadowsocks, я использую обычно ufw интерфейс к iptables, но можно настроить напрямую задав правила iptables

# Очистка всех правил iptables
ufw disable
ufw reset
ufw default deny incoming
ufw default allow outgoing

iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT

# Добавление базовых правил
ufw allow 'OpenSSH'

# потребуется для настройки v2ray
ufw allow 'Nginx Full'

# этот порт оставляем для shadowsock
ufw allow 8080/tcp

# Проверем! Тут важно, если порт SSH не открыт то сессия будет завершена и вы не сможете подключиться снова
ufw list

# если все верно, то включаем 
ufw enable

Теперь нужно приступить к установки плагина для shadowsocks. В моей системе на сервере его не было поэтому я скачивал из репозитория, только перед скачиванием архива нужно проверить какая у вас система на сервере и выбрать подходящий архив для своей системы ( amd64/368/etc )

wget https://github.com/shadowsocks/v2ray-plugin/releases/download/v1.3.2/v2ray-plugin-linux-386-v1.3.2.tar.gz
tar -xzf v2ray-plugin-linux-368-*.tar.gz
mv v2ray-plugin_linux_amd64 /usr/local/bin/v2ray-plugin
chmod +x /usr/local/bin/v2ray-plugin

Теперь нужно поправить конифги сервера shadawsocks ( ss-server ) я создал конфиг в директории /etc для этого, но его можно создать где угодно, главное при запуске ss-server указать путь к нему

{
    "server":["0.0.0.0","::1"],
    "mode":"tcp_and_udp",
    "server_port":8080,
    "password":"password",
    "timeout":300,
    "method":"chacha20-ietf-poly1305",
    "plugin": "v2ray-plugin",
    "plugin_opts": "server;tls;host=mydomain.ru;cert=/etc/letsencrypt/archive/mydomain.ru/fullchain1.pem;key=/etc/letsencrypt/archive/mydomain.ru/privkey1.pem",
    "fast_open": true
}

Теперь подробнее об параметрах:

  • server — тут нужно указать ip по которым можно будет подключаться к серверу по протоколу shadowsock для создания зашифрованого туннеля, 0.0.0.0 — разрешает все подключения для ip4, ::1 — разрешает все подключения для ip6 соответственно
  • mode — разрешает устанавливать соединение и по tcp и по udp
  • password — пароль подключения
  • method — метод шифрования, в данном случае приведен метод chacha20-ietf-poly1305 это быстрый безопасный метод потокового шифрования, если по каким-то причинам нужен другой, то список поддерживаемых методов можно узнать командой ss-server —help
  • plugin — подключаем плагин маскировки v2ray-plugin
  • plugin_opts — тут передаются настройки для плагина v2ray-plugin, но о них я напишу далее более подробно
  • fast_open — ускоряет tcp соединение

Тут требуется более подробно остановится на плагине и переданных опциях

v2ray-plugin для Shadowsocks — это плагин, который добавляет поддержку протокола VMess (из проекта V2Ray) к Shadowsocks, маскируя трафик под обычный HTTPS и улучшая обход блокировок. Для того чтобы он заработал потребуется реальный домен и сертификат безопасности ( подойдет letsencrypt ), поэтому на данном этапе нужно запустить web сервер и привязать к нему какой-либо домен или субдомен, например, вот так можно настроить nginx для v2ray:

server {
    if ($host = mydomain.ru) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    listen 80;
    server_name mydomain.ru;
    return 301 https://$host$request_uri;


}

server {
    listen 443 ssl;
    server_name mydomain.ru;

    location / {
        # Встраиваем плеер с радио (пример для Lofi Girl)
        add_header Content-Type text/html;
        return 200 '
<!DOCTYPE html>
<html>
<head>
    <title>Стрим 24 онлайн</title>
</head>
<body>
    <iframe 
	src="https://www.youtube.com/embed/jfKfPfyJRdk?autoplay=1"
        allow="autoplay; fullscreen" 
        allowfullscreen
    ></iframe>
</body>
</html>
        ';
    }
    ssl_certificate /etc/letsencrypt/live/mydomain.ru/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/mydomain.ru/privkey.pem; # managed by Certbot

}

Как видите тут для примера я использовал генерацию сертификатов командой Cerbot но можно создать сертификат любым способом. После настройки web сервера и создания сертификатов под ваш домен требуется прописать пути к сертификату в настройках плагина в shadownsock.json

server;tls;host=mydomain.ru;cert=/etc/letsencrypt/archive/mydomain.ru/fullchain1.pem;key=/etc/letsencrypt/archive/mydomain.ru/privkey1.pem

тут важно отметить, что в конфигрурации сервера в опциях плагина вначале требуется указать server и еще один важный момент, опция не понимает путь к символьной ссылке поэтому потребуется указать путь на реальный файл ( не знаю почему так, но с указанием символьной ссылки у меня не получилось запуститься ) так же нужно будет учитывать это при обновлении сертификата ( например в кроджобе автоматического обновления сертификата можно указать так же выполнение своего скрипта который будет редактировать /etc/shadowsock.json и прописывать путь к актуальным обновленным сертфикатам

На этом в целом настройка конфига на сервере закончина. Далее потребуется перезапустить сам сервис. В прошлой статье про shadownsock я показывал как запустить ss сервер при помощи сервиса из пакета shadowsocks-libev но с добавлением плагина v2ray перестал работать запуск поэтому я решил написать свою службу для запуска, тут приведу интсрукции как создать новую службу и добавить ее в systemctl на сервер с Ubuntu

vim /etc/systemd/system/shadowsocks.service

и добавляем туда

[Unit]
Description=Shadowsocks Server with V2Ray-Plugin
After=network.target

[Service]
Type=simple

# Запуск сервера с подготовленным конфигом с плагином v2ray
ExecStart=/usr/bin/ss-server -c /etc/shadowsocks.json
Restart=always
RestartSec=3
Environment="HOME=/tmp"

# Если используете TLS-сертификаты:
ReadWritePaths=/etc/letsencrypt/live/mydomain.ru/
ReadWritePaths=/etc/letsencrypt/archive/mydomain.ru/
NoNewPrivileges=no

[Install]
WantedBy=multi-user.target
~                               

После добавления регистрируем новую службу командой

systemctl daemon-reload

И запускаем сервис

systemctl start shadowsocks
systemctl enable shadowsocks

На этом серверная часть готова и можно переходить к настройкам клиента.

Есть множество клиентов для разных систем и мобильных ОС, я решил использовать для себя самый простой консольный клиент ss-local а для этого потребуется установить его на ваш компьютер в зависимости от того какая у вас система, на маке это выглядет так

brew install shadowsocks-libev

И установка вручную плагина v2ray так как в репозитории brew его нет

wget https://github.com/shadowsocks/v2ray-plugin/releases/download/v1.3.2/v2ray-plugin-darwin-amd64-v1.3.2.tar.gz
tar -xzf v2ray-plugin-darwin-amd64-v1.3.2.tar.gz
sudo mv v2ray-plugin_darwin_amd64 /usr/local/bin/v2ray-plugin
sudo chmod +x /usr/local/bin/v2ray-plugin

И далее я реализовал небольшой скрипт bash для использования ss-local

vim ss-tunnel.sh
#!/bin/bash

# Путь к конфигурационному файлу
CONFIG_FILE="$HOME/.ss/config.json"
LOG_FILE="/tmp/ss-local.log"

# Проверяем наличие конфига
if [ ! -f "$CONFIG_FILE" ]; then
    echo -e "\033[31mОшибка:\033[0m Конфигурационный файл $CONFIG_FILE не найден."
    exit 1
fi

# Получаем локальный порт из конфига
LOCAL_PORT=$(jq -r '.local_port' "$CONFIG_FILE" 2>/dev/null || {
    echo -e "\033[33mПредупреждение:\033[0m Не удалось прочитать local_port, используем 1080"
    echo "1080"
})

ss_stop() {
   pkill -f "ss-local -c $CONFIG_FILE"
}

ss_start() {
    echo "Запускаем ss-local с конфигом $CONFIG_FILE..."
    ss-local -c "$CONFIG_FILE" -v &> "$LOG_FILE" &
    SS_LOCAL_PID=$!

    # Даем время на подключение
    for i in {1..5}; do
        echo -n "."
        sleep 1
    done
    echo
}

ss_check() {
    CHECK_URL="https://ifconfig.me"
    echo "Проверяем подключение через SOCKS5 (порт $LOCAL_PORT)..."
    if curl --socks5 "127.0.0.1:$LOCAL_PORT" --connect-timeout 10 -s "$CHECK_URL" &> /dev/null; then
        EXTERNAL_IP=$(curl --socks5 "127.0.0.1:$LOCAL_PORT" -s "$CHECK_URL")
        echo -e "\033[32mУспех!\033[0m Туннель работает. Ваш внешний IP: $EXTERNAL_IP"
        echo "Для остановки выполните: pkill -f 'ss-local -c $CONFIG_FILE'"
    else
        echo -e "\033[31mОшибка!\033[0m Не удалось подключиться через туннель."
        echo "Последние строки лога:"
        tail -n 5 "$LOG_FILE"
        kill -9 "$SS_LOCAL_PID" &> /dev/null
        exit 1
    fi
}

ss_log() {
    tail -f $LOG_FILE
}

ss_status() {
  if lsof -i :1080 >/dev/null 2>&1; then
    echo
    echo "🟢 PROXY: 1080"
    echo
  else
    echo
    echo "🔴 PROXY: DISCONECT"
    echo
  fi
}

case "$1" in
    start)
        ss_start
	;;
    stop)
        ss_stop
        ;;
    restart)
        ss_stop
        sleep 2
        ss_start
        ;;
    status)
        ss_status
        ;;
    log)
        ss_log
        ;;
    *)
        echo "Использование: $0 {start|stop|restart|status|log}"
        exit 1
esac

exit 0

Основная команда запуска тут ss-local -c «$CONFIG_FILE» -v &> «$LOG_FILE» &

в которую передается конфиг $CONFIG_FILE, я использую отдельную директорию в домашней директории пользователя для хранения конфига ~/.ss/config.json

Содержимое config.json на стороне клиента должно быть таким:

{
    "server": "<ip_server>",
    "server_port": 8080,
    "local_port": 1080,
    "password": "password",
    "method": "chacha20-ietf-poly1305",
    "plugin": "v2ray-plugin",
    "plugin_opts": "tls;host=mydomain.ru",
    "timeout": 300
}

Тут более менее понятно:

  • server — указываете ip вашего сервера
  • server_port — указываете порт сервера на котором запущен ss ( мы настроили выше сервер на раобту с портом 8080 )
  • local_port — указывается локальный порт клиента на котором будет стартовать sock5 служба
  • plugin — v2ray для маскировки трафика
  • method — должен совпадать с серверным методом шифрования
  • plugin_opts — тут нужно указать tsl; и ваш реальный домен на вашем хосте сертификаты которого прописаны в серверном конфиге

Все! После теперь можно добавить прав скрипту и можно попробовать запустить тоннель shadownsocks замаскерованный под https запрос

chmod +x ss-tonnel.sh
./ss-tunnel.sh 

После этого должна запуститься служба на порту 1080 через которую можно будет подключить приложение поддерживающие прокси соединения для установки безопасного замаскированного канала соединения. Проверить можно например исполнив команду curl с подключением через прокси на 1080 порту

curl --socks5 "127.0.0.1:1080 https://ifconfig.me

В ответ на команду должен прейти ответ с ip сервера

Что можно добавить из плюшек, например, если вы хотите пропустить весь трафик через защищенный замаскированный канал, то используйте VPN подключенный через ss тоннель.

Для мониторинга соединения можно использовать небольшой скрипт в .zshrc который будет отображать активность proxy

vim ~/.zshrc

...
function proxy_status() {
  if lsof -i :1080 >/dev/null 2>&1; then
    echo "🟢 PROXY: %F{green}1080%f"
  else
    echo "🔴 PROXY: %F{red}DISCONECT%f"
  fi
}
...

# автообновление промпта
TMOUT=5

# и далее в удобное место добавляете PROMPT='... $(proxy_status) ... '
# для 

На этом пока что все.

, ,

5 декабря, 2024

Netcat: универсальный швейцарский нож для сетевых операций

Давно на этом сайте не было статей про unix way подход. Не было ничего насчет инструментов командной строки, который нельзя игнорировать даже в наш век сложных UI UX инструментов, командная строка остается один из самых эффективных инструментов в профессиях связанных с IT индустрией, поэтому тут хотел бы рассказать и привести примеры взаимодействия с сетью через такую замечательную команду как netcat доступная в большинстве дестрибутивом unix подобных систем

Итак, поехали!

Netcat (nc) — это маленькая, но мощная утилита в мире UNIX, которая часто упоминается как «швейцарский нож» для сетевых операций. Она позволяет нам отправлять и принимать данные по сети, а также может заменить сразу несколько специализированных утилит. В этой статье мы разберём, как nc может облегчить жизнь системного администратора, разработчика, а также просто энтузиаста, заинтересованного в исследовании сетевых возможностей.

Зачем нужен Netcat?

Использование nc может быть полезно для диагностики сети, передачи файлов, отладки сетевых приложений и даже создания простых серверов и клиентов. Главный плюс — это гибкость nc и поддержка широкого диапазона сетевых протоколов и операций.

Установка Netcat

В большинстве UNIX-систем Netcat уже установлен. Но если вдруг у вас его нет, можно легко добавить его через менеджер пакетов:

# На Debian/Ubuntu
sudo apt install netcat

# На CentOS/RHEL
sudo yum install nc

# На MacOS
brew install netcat

Теперь, когда nc у нас на борту, давайте разберёмся с реальными примерами использования.

1. Диагностика открытых портов

Вы хотите узнать, открыт ли определённый порт на сервере, или, возможно, провести быструю диагностику состояния сети? Netcat может помочь!

nc -zv example.com 80
  • -z — режим проверки портов (без отправки данных).
  • -v — включение режима подробного вывода (verbose).

Пример вывода:

Connection to example.com 80 port [tcp/http] succeeded!

Этот трюк полезен для быстрого анализа открытых портов на сервере, например, при проверке, работает ли сервер после перезагрузки.

2. Передача файлов

Netcat можно использовать для передачи файлов по сети — простой и быстрый способ отправить что-то, не прибегая к сложным утилитам.

На стороне отправителя (отправка файла):

cat myfile.txt | nc -l 1234

На стороне получателя (приём файла):

nc <IP-адрес> 1234 > receivedfile.txt

После выполнения этих команд содержимое myfile.txt на отправляющей стороне будет передано и сохранено как receivedfile.txt на принимающей стороне. Эта опция отлично подходит для работы в рамках одного сегмента сети или виртуальной среды.

3. Запуск простого сервера или тестового чата

Допустим, вы хотите создать простой сервер для прослушивания на определённом порту, чтобы принимать текстовые сообщения или проверять сетевые соединения. Netcat справится с этим в два счёта!

# Серверная сторона
nc -l 5555

Сервер готов и прослушивает подключение на порту 5555. Теперь на клиентской стороне подключаемся к этому порту:

# Клиентская сторона
nc <IP-адрес сервера> 5555

Теперь у нас есть простой чат-сервер! Всё, что вы набираете на стороне клиента, будет отображаться на сервере, и наоборот. Этот метод часто используется для тестирования или отладки сетевых соединений и приложений в реальном времени.

4. Реализация теста скорости сети

С помощью nc и pv (pipe viewer) можно провести тест скорости сети, чтобы понять, насколько хорошо она работает. В этом случае pv отправляет данные через nc, и это полезно, когда требуется быстро протестировать локальную сеть.

На серверной стороне:

nc -l 5555 > /dev/null

На клиентской стороне:

pv /dev/zero | nc <IP-адрес сервера> 5555

Такой тест позволяет вам видеть скорость передачи данных в режиме реального времени, что может быть полезно для диагностики проблем с сетью.

5. Проверка DNS-серверов и отправка DNS-запросов

С помощью nc можно отправить DNS-запрос напрямую на сервер для отладки или диагностики.

Например, чтобы отправить DNS-запрос на определённый сервер, можно использовать комбинацию с echo:

echo -e "\x12\x34\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x03www\x06google\x03com\x00\x00\x01\x00\x01" | nc -u 8.8.8.8 53
  • Команда echo -e создаёт DNS-запрос в шестнадцатеричном формате, чтобы запросить www.google.com.
  • -u указывает, что нужно использовать UDP, так как DNS работает на этом протоколе.

Это полезно для диагностики сетевых проблем и проверки того, как работает DNS-сервер.

6. Мониторинг TCP и UDP портов (сетевой сниффер)

Netcat может быть использован как базовый сетевой сниффер для мониторинга входящих данных на портах. Например, если нужно прослушивать UDP-порт на 5555:

nc -u -l 5555

Этот режим полезен для диагностики UDP-соединений или проверки активности на порту, особенно если данные передаются по сети случайным образом.

7. Проверка доступности веб-сайта и получение HTTP-заголовков

С помощью nc можно проверить, правильно ли работает веб-сервер, отправив к нему HTTP-запрос и получив заголовки ответа.

echo -e "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n" | nc example.com 80

Этот запрос отправляет простую команду GET на сервер example.com, и Netcat возвращает HTTP-заголовки, позволяя увидеть статус-сообщение и понять, отвечает ли сервер.

8. Создание резервной копии диска через сеть

Netcat можно использовать для копирования содержимого одного жесткого диска на другой через сеть. Этот метод подойдёт для создания резервных копий или клонирования.

На стороне отправителя:

dd if=/dev/sda | nc -l 1234

На стороне получателя:

nc <IP-адрес отправителя> 1234 | dd of=/dev/sdb

Здесь dd используется для чтения данных с диска, а nc передаёт эти данные по сети на другой диск. Это эффективный способ, но требует осторожности, так как данные могут быть перезаписаны.

9. Отправка сообщений в чат в несколько потоков

Netcat можно настроить для создания текстового чата между несколькими пользователями, что пригодится, например, для координации действий в одной сети.

На стороне сервера:

mkfifo mypipe
nc -l 1234 < mypipe | tee mypipe

На стороне клиента:

nc <IP-адрес сервера> 1234

Тут мы используем именованный канал (FIFO) mypipe для передачи данных в двух направлениях. Это позволяет передавать сообщения от всех подключённых клиентов серверу и обратно.

10. Сканирование диапазона портов на удалённом сервере

Netcat может быть использован для быстрого сканирования диапазона портов, чтобы узнать, какие из них открыты. Хотя это и не заменяет полноценные сканеры (как nmap), Netcat предоставляет простое решение.

for port in {20..25}; do
  echo "" | nc -v -w 1 -z example.com $port
done
  • -w 1 устанавливает таймаут в 1 секунду.
  • -z указывает на то, что нам нужно только проверить открытость порта, не отправляя данных.

Это полезно для быстрого анализа доступных портов на целевом сервере.

11. Организация обратного подключения для удалённого доступа

Для отладки или диагностики можно организовать обратное подключение с использованием nc, чтобы получить доступ к удалённой системе.

На целевой стороне:

nc -l -p 1234 -e /bin/bash

На управляющей стороне:

nc <IP-адрес целевой машины> 1234

После подключения управляющая сторона сможет получить доступ к командной строке удалённого сервера. Однако важно помнить, что этот метод небезопасен и должен использоваться только в закрытых и безопасных средах.

12. Перехват и просмотр трафика на локальном интерфейсе

Перехват и просмотр трафика на локальном интерфейсе

Если вы хотите быстро посмотреть, что за трафик проходит через ваш локальный интерфейс, можно использовать комбинацию nc и tcpdump.

tcpdump -i eth0 -s0 -w - | nc -l 1234

Эта команда захватывает трафик на интерфейсе eth0 и передаёт его через nc для анализа. На другой стороне можно подключиться к этому порту и просматривать трафик в реальном времени.

Ну и немного совсем экзотических примеров использования команды nc

13. Создание простого веб-сервера на базе nc

С помощью nc можно запустить минималистичный HTTP-сервер на своём компьютере, который будет отдавать статический файл или HTML-страницу. Это может пригодиться для быстрой демонстрации или тестирования локально без полноценного веб-сервера.

Пример команды для одностраничного веб-сервера:

while true; do echo -e "HTTP/1.1 200 OK\r\nContent-Length: $(wc -c < index.html)\r\n\r\n$(cat index.html)" | nc -l -p 8080; done
  • Эта команда запускает бесконечный цикл, который отдаёт содержимое файла index.html по HTTP на порт 8080.
  • Подойдёт для тестов, проверки HTTP-запросов и небольших демонстраций.

Теперь, зайдя на http://localhost:8080 в браузере, можно увидеть содержимое index.html.

14. Туннелирование TCP-порта через UDP (обход блокировок)

Когда на брандмауэре разрешены только UDP-порты, nc можно использовать для проброса TCP-трафика через UDP, обходя тем самым блокировки на уровне сети. Это немного хакерский метод, но работает в специфичных случаях.

Серверная сторона (UDP к TCP-туннель):

nc -u -l -p 5555 | nc localhost 80

Здесь nc принимает UDP-пакеты на порту 5555 и перенаправляет их к TCP-соединению на локальный порт 80 (обычно HTTP).

Клиентская сторона:

echo "GET / HTTP/1.1\r\nHost: localhost\r\n\r\n" | nc -u <IP-адрес сервера> 5555

Таким образом можно протестировать HTTP через UDP, например, когда нужно обойти некоторые ограничения сетевых правил.

15. Переключатель музыки или медиа-сервера через аудиопоток

С помощью nc можно создать простое потоковое аудио- или видеовещание. Например, для проигрывания музыки на другой машине по сети.

На стороне отправителя:

cat song.mp3 | nc -l -p 4000

На стороне получателя:

nc <IP-адрес отправителя> 4000 | mpv -
  • Эта команда передаёт файл song.mp3 через nc, а на принимающей стороне поток воспроизводится плеером mpv.
  • Подходит для потоковой передачи аудиофайлов или даже видео через локальную сеть без сложной настройки.

16. Координация команд в кластере

Если у вас есть несколько серверов, и вам нужно выполнить одну и ту же команду на каждом из них, nc можно использовать для координации. Один сервер действует как мастер, отправляя команды всем остальным.

На сервере-мастере:

echo "ls -l /home" | nc -w 1 <IP-адрес сервера1> 1234
echo "ls -l /home" | nc -w 1 <IP-адрес сервера2> 1234

На каждом из серверов:

nc -l 1234 | bash
  • Эта команда отправляет ls -l /home от мастера, и все серверы её выполняют.
  • Применимо для быстрой автоматизации команд или тестирования на нескольких серверах без сложной настройки.

17. Секретное сообщение с самоуничтожением

Можно отправить сообщение через nc с таймером самоуничтожения, чтобы оно удалилось сразу после прочтения, как в шпионских фильмах.

На стороне отправителя:

echo "Это сообщение самоуничтожится через 5 секунд" | nc -l -p 5000

На стороне получателя:

nc <IP-адрес отправителя> 5000 && sleep 5 && echo "Сообщение удалено"

После того как сообщение прочитано, команда sleep 5 завершает выполнение через 5 секунд, и на экране выводится сообщение о том, что оно было «удалено».

На этом пока что все. Буду время от времени еще выкладывать интересные инструменты командный строки.

, , ,

7 ноября, 2024

Устанавливаем Shadowsocks на свой сервер

Для начала стоит объяснить, что такое Shadowsocks и для чего он может быть полезен.

Иногда вы можете оказаться в сети с ограничениями, где фильтруется интернет-трафик, и доступ к определённым ресурсам блокируется. Такие ограничения могут встречаться, например, в корпоративной сети на работе. Если вам необходимо обойти такие блокировки и получить доступ к нужным сайтам, на помощь может прийти инструмент под названием Shadowsocks. По сути, это прокси-сервер, который использует протокол SOCKS5 для передачи данных.

Протокол SOCKS5 позволяет создать зашифрованное соединение и направлять трафик через него, делая его менее заметным для фильтров и блокировок. В этой статье я расскажу, как быстро развернуть свой прокси-сервер с использованием Shadowsocks. Чем-то это напоминает создание шифрованного тоннеля через ssh.

Для начала вам необходим свой сервер. Если у вас еще нет своего сервера, то переходите по ссылке и зарегистрируйте его. Хостинг дает сутки на тестирование, поэтому можно проверить как работает тот же sadownsocks, например.

После того как у вас появился свой сервер, необходимо установить shadowsocks
это легко сделать при помощи нескольких команд:

$ sudo apt update
$ sudo apt install shadowsocks-libev

Теперь нужно создать основной файл с настройками shadowsocks. Поэтому создаем в /etc/shadowsocks-libev файл config.json со следующем содержимым:

{
    "server": "[server]",
    "server_port": "[server_port]",
    "password":"[password]",
    "mode":"tcp_and_udp",
    "timeout": 300,
    "local_port": "[local_port]",
    "method": "xchacha20-ietf-poly1305",
    "fast_open": true,
    "nameserver": "8.8.8.8"
}

server — ip адрес сервера
server_port — сервер порт через который будет создан тоннель ( замените на свой )
password — пароль подключения ( замените на свой )
method — метод шифрования ( если не уверены, то лучше оставить такой как в примере )
local_port — порт на локальной машине через который будет проходить зашифрованный трафик

Если у вас на сервере установлен файрвол, то необходимо открыть порт, который был указан в настройках:

$ sudo ufw allow [server_port]
$ sudo ufw reload

Теперь можно запустить shadowsocks:

$ sudo systemctl restart shadowsocks-libev

После этого на сервере все готово и можно приступать к настройке клиентской части.

Для того, чтобы запустить зашифрованный socks5 на вашей локальной машине потребуется установить Shadowsocks клиент. Вот несколько вариантов для разных систем:

Windows

  1. Shadowsocks for Windows — Официальный клиент с графическим интерфейсом.
  2. ShadowsocksR — Модифицированная версия Shadowsocks, поддерживающая дополнительные шифрования и функции.
  3. Outline — Простой в использовании клиент, который также поддерживает Shadowsocks и удобен для новичков.

macOS

  1. ShadowsocksX-NG — Популярный клиент для macOS с поддержкой Shadowsocks и дополнительными функциями.
  2. Outline — Также доступен для macOS, позволяет легко подключаться к Shadowsocks-серверам.

Linux

  1. Shadowsocks-libev — Лёгкий клиент для Linux, поддерживающий командную строку и простой в настройке.
  2. Outline — Клиент с графическим интерфейсом, доступный для нескольких версий Linux.
  3. Shadowsocks-qt5 — Версия с графическим интерфейсом, подходящая для пользователей, предпочитающих GUI.

Android

  1. Shadowsocks for Android — Официальное приложение для Android с поддержкой настроек и переключений.
  2. ShadowsocksR Android — Вариант с дополнительными настройками и функциями.
  3. Outline — Отличный вариант для пользователей, которые хотят быстро подключиться без сложных настроек.

iOS

Outline — Простое и удобное приложение, особенно для начинающих.

Shadowrocket — Один из самых популярных и мощных клиентов для iOS, поддерживает Shadowsocks и другие протоколы.

Potatso Lite — Поддерживает Shadowsocks и имеет удобный интерфейс.

Выбираем подходащий клиент и настраиваем соединение в нем для сервера на который поставили shadwonsocks

После установки соединения SOCKS5 будет доступен на локальной машине на порту local_port который ранее мы указали в настройках shadownsock на сервере

Ну вот и все. Следите за обновлениями в телеграме, чуть позже планирую написать продолжение по данной тематики.

, ,

30 июля, 2024

Обычный SSH тоннель

Понимаю, что банальность, но пусть будет.

Часто требуется подключится к базе данных mysql боевого сервера, но порт 3306 доступен только в localhost, для решения этой тривиальной задачи нам поможет ssh тоннель.

ssh -f -N -L 3307:localhost:3306 remote_host

Теперь в вашем localhost будет доступен порт 3307 через который вы сможете подключится к базе данных mysql на боевом хосте

-f запуск в фоне 
-N не выполнять команду (без нее и -f запустить шел на удаленном хосте)
-L перенаправление портов

апдейд:

Далее для удобства можем создать алиас для этого дела, чтобы быстрее можно было создать тоннель. Вот так это будет выглядеть для zsh под MacOS

$ vim ~/.zshrc

вставляем эту строку в конце файла

<br>alias create_tonnel="ssh -f -N -L 3307:localhost:3306 remote_host"

и выходим из vim

:wq

, ,

3 августа, 2012

Групповое переименование файлов по маске

По долгу службы встала задача переименовать группу файлов в директории по маске ( убрать у php файлов префикс и постфикс ).
Исходные файлы вида aqNameClass.class.php нужно привести к виду NameClass.php

Решается эта задача одной командой shell:

for i in *.class.php; do mv "$i" `echo "$i" | sed "s/\.class//" | sed "s/^aq//"`; done

, ,

9 июля, 2012

Монтирование SD карты с правами пользователя в arch linux

Задача:

примонтировать SD карту на 64G как дополнительный жесткий диск, чтобы не-root мог читать ее и записывать в нее.

Решение:

mount -o uid=<uid> /dev/<dev_id> /mnt/<mount_point>

где,

<uid> — id пользователя ( узнать можно командой id или посмотреть в /etc/passwd )

<dev_id> — устройство sd карты

<mount_point> — каталог в который будет примонтирована SD-карта.

в /etc/fstab добавляем опцию монтированя uid=<uid>

и всё.

28 июля, 2010

Скрипт добавления нового виртуального хоста

Как-то поднадоело мне постоянно редактировать вручную httpd.conf и /etc/hosts и я решил написать скрипт, который бы позволил автоматизировать этот процесс
Вот такой скрипт:

#!/bin/sh

# Константы:
HOSTS='/tc/hosts'; # Путь к файлу hosts
HTTPD_CONF='/etc/httpd/conf/extra/httpd-vhosts.conf';

# Путь к файлу с настройками виртуальных хостов
DIR_HTTP='/srv/http/'; # Путь к директориям с хостами
IP_MASK='127.0.0.'; # Маска по которой будет формироваться новый IP
INDEX_FILE='index.php'; # Index файл в корневой папке нового виртуального хоста
DIR_LOG='/var/log/httpd/'; # Путь к папке с логами
EMAIL_ADMIN='wikide@gmail.com'; # Email админестратора

# Функция вывода ошибок
get_error() {
    echo $1;
    exit 0;
}

# Функция проверки ip
check_ip() {
    if [ "`cat $HOSTS | grep \"$ip\"`" ]; then
        echo 1;
    fi
}

# Проверяем наличея параметра с именем хоста
if [ "$1" ]; then
    if [ "$2" ]; then
        # Если задан свой IP
        new_ip=$2;
        if [ "`check_ip $new_ip`" ]; then # Проверка на наличее в файле
            get_error 'Такой ip адрес - '$new_ip' уже занят. Введите другой или пусть скрипт '$0' сам сгенерирует ip адресс для нового хоста.';
        fi;
    else
        # Получаем IP автоматически
        new_ip=$IP_MASK$((`tail -1 $HOSTS | awk '{ split($1, ip, "."); print ip[4]}'`+1));
    fi

    # Если корневая папка нового хоста уже существует
    if [ -d $DIR_HTTP$1/ ]; then
        get_error 'Директория '$1' уже есть в '$DIR_HTTP'. Подберите другое имя.';
    else
        # Создаем корневую директорию виртуального хоста
        mkdir $DIR_HTTP$1;
        echo -e "
    <html>
     <head>
      <title>New host</title>
     </head>
     <body>
        <h1>Created host '$1'!</h1>
     </body>
    </html>" > $DIR_HTTP$1'/index.php';
  
    # Запись в hosts
        sudo echo $new_ip  $1 | sudo tee -a $HOSTS 1>/dev/null;

    # Запись в конфиг Apache
        sudo echo -e "#Create date: `date '+%F %T'`
          DirectoryIndex $INDEX_FILE
          ServerAdmin $EMAIL_ADMIN
          DocumentRoot \"$DIR_HTTP$1/\"
          ServerName $1
          ServerAlias $1
          ErrorLog \"$DIR_LOG$1.log\"
          CustomLog \"$DIR_LOG$1\" common" | sudo tee -a $HTTPD_CONF 1>/dev/null;

        # Перезапускаем сервер
        sudo apachectl restart;

        # Выводими сообщение

        echo 'Виртуальный хост "'$1'" успешно создан'
    fi
else
    get_error 'Нужно обязательно указать название нового хоста $0 NAME_HOST [IP_HOST]';
fi

exit 0;

,

27 июля, 2010

Скрипт запуска wifi в ARCH Linux

Небольшой скрипт для подключения к сетям wifi в ARCH linux

#!/bin/bash

# Определяем интрфейс ( в моем случае это - wlan0)
if [ "$2" ]; then 
	dev=$2;
else 
	dev="wlan0";
fi

# Действие
case "$1" in
	start)
		sudo ifconfig $dev up;
		sudo wpa_supplicant -B -i$dev -c/etc/wpa_supplicant.conf;
		sleep 3;
		sudo dhcpcd $dev 2&gt;/dev/null;
	;;
	stop)	
		sudo killall -9 dhcpcd 3&gt;/dev/null;
		sudo killall -9 wpa_supplicant 3&gt;/dev/null;
		sudo ifconfig $dev down;
	;;
	list)
		sudo ifconfig $dev up;
		sleep 1;
		sudo iwlist $dev scanning;
		sudo ifconfig $dev down;
	;;
	restart)
		$0 stop;
		$0 start;
	;;
	status)
		echo -n 'IP arrdess: '; ifconfig wlan0 | grep "inet addr" | awk '{print $2}' | sed 's/addr://'
		echo -n "Essid: "; iwconfig wlan0 | grep "Ralink STA" | awk '{print $4}' | sed 's/ESSID://'
	;;
	*)

	if [ "$1"  ]; then
		echo "usage: $0 {start|stop|list|restart}"; 
	else 
		echo "Restarting";
		$0 restart;
	fi

esac

exit 0

Вот такой вот скрипт :)

,

26 июля, 2010

Статус аккумулятора в приглашении командной строки

Вот очередной велосипед на тему показа статуса аккумулятора для нэтбука на ARCH Linux :)

Вот такой получается скрипт на sh (думаю все ясно из комментов):

#!/bin/zsh

# Определяем уровень заряда аккумулятора на текущий момент
remaining_bat=`cat /proc/acpi/battery/BAT0/state | grep remaining | awk {'print $3'}`;

# Определяем 100% заряда для аккумулятора
full_bat=`cat /proc/acpi/battery/BAT0/info | grep full | awk {'print $4'}`;

# Определяем подключён сетевой провод или нет
stat=`cat /proc/acpi/battery/BAT0/state | grep charging | awk {'print $3'}`;

if [ $stat = 'charging' ]; then
stat='+'; # Провод подключён ( ноут зяряжеается )
else if [ $stat = 'charged' ]; then
stat=''; # ( Аккумулятор зяряжен)
else
stat='-'; # Провод не подключён ( ноут разряжается )
fi
fi

# получаем заряд батареи в % ( Школьная математика - Рулит! :) )
bat=$(($remaining_bat*100/$full_bat));

# основные цвета ( ESC - последовательности, подробнее - $ man console_codes )
RED="\033[31m"; # Красный
YELLOW="\033[33m"; # Жёлтый
WHITE="\033[38m"; # Белый

# Цвет по-умолчанию
DEFAULT="\033[0m";

if [ $bat -lt 10 ]; then # Если заряд аккамулятора меньше 10% (краасные цвет)
result="$RED$stat$bat";
else if [ $bat -lt 30 ]; then # Если заряд аккамулятора меньше 30% (жёлтый цвет)
result="$YELLOW$stat$bat";
else
result="$WHTE$stat$bat"; # Заряд аккамулятора больше 30% ( белый цвет )
fi
fi

# Выводим результат
echo -e $result%%$DEFAULT;

exit 0;

Далее говорим zsh о том, что нужно выводить в PROMPT результат этого скрипта.
В файле ~/.zshrc в функции precmd() прописываем где-нибудь в начале:

precmd() {
   BAT=`binf.sh`;
   PROMPT="battery:(`echo $BAT`)::%{$reset_color%}%{$fg_bold[green]%}%m {$reset_color%}::%{$fg_bold[crey]%}[ %~ ]%{$rese+t_color%}&gt; "
.....

Как-то вот так, где binf.sh — скрипт выше.
Обязательно нужно, чтобы binf.sh лежал по пути в переменной PATH, я для этой цели создал папку bin в домашней директории и сделал ссылку на файл в папке /bin

В precmd() — можно запихнуть любые команды, которые будут выполнятся при обновлении командной строки.