Természetesen ez az oldal is használ cookie-kat.
Nem tetszik?

Nem, elmegyek
home

T  h  e
D a r k
S i t e

Magánjellegű internetes dokumentációs és publikációs felület és kísérleti weboldal a Morkpy tartalomkezelő rendszer fejlesztési folyamatainak tesztelésére és szemléltetésére

Rovat: Dokumentáció

Dokumentáció Koppánynak

dark Blog 2023-08-09 10:46:00


A csomagkezelő

Nem írom oda, hogy  sudo . Látni fogod, ha kell. Fontos, hogy soha ne használj  sudo -t, ha nem feltétlenül szükséges, mert baj lehet belőle, nagy. A logika mondjuk az, hogy akkor kell  sudo , ha a rendszer egészét érintő változást akarsz előidézni. Telepítéshez tehát kell, kereséshez nem.

Csomaglista frissítése

apt update

Csomag keresése

apt-cache search valami

Telepítés

apt install valami


Docker login

dark Dokumentáció 2023-06-16 09:18:00

Ha a docker login sipákol a dbus miatt.


Azaz a

docker login

eredménye például az, hogy

error getting credentials - err: exit status 1, out: `GDBus.Error:org.freedesktop.DBus.Error.ServiceUnknown: The name org.freedesktop.secrets was not provided by any .service files`

akkor

A megoldás az, hogy

apt install gnupg2 pass



Szpem és vírus szűrő tesztelése

dark Dokumentáció 2023-02-18 11:42:00

Ezek olyan sztringek, amiket beteszünk emailbe, elküldjük magunknak, nézzük a levelező szerver logokat, és ha azt látjuk, hogy a levelek kiszűrődtek, akkor örvendezünk.


Szpem teszt

XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X

Vírus


Frissítés (2023.04.29.)

Igen, a kibaszott vírus teszt sztring baszik megjelenni, mert olyan karakterek vannak benne, amik miatt a szarul megírt formázókód értelmező elbassza az egész tartalmat.

Robot Cimbora véleménye:

Programozóként a hibák vagy hibák találkozása a fejlesztési folyamat természetes része, és fontos nyugodtnak és összpontosítottnak maradni a probléma hatékony hibakereséséhez és javításához.

A düh kifejezése helyett konstruktívabb lenne alaposan áttekinteni a kódot, azonosítani a probléma forrását és dolgozni a megoldáson. A hibakeresés frusztráló folyamat lehet, de pozitív hozzáállás és problémamegoldó szemléletmód fenntartása a siker kulcsa.



Docker mocsok eltakarítása

dark Dokumentáció 2022-11-10 10:51:00


docker system prune -a --volumes
truncate -s 0 /var/lib/docker/containers/*/*-json.log

--all	-a		Remove all unused images not just dangling ones
--force	-f		Do not prompt for confirmation
--volumes		Prune anonymous volumes


OpenVPN kulcsok kezelése easy-rsa-val

dark Dokumentáció 2022-11-01 08:21:00


Másoljuk az easy-rsa könyvtárat az /etc/openvpn alá

cd /etc/openvpn
cp -r /usr/share/easy-rsa/ .
cd easy-rsa

Vidáman létrehozzuk a nyilvános kulcsú infrastruktúrát, a dh cserekulcsot, a tanúsító kulcsot, a szerver kulcsot és tanúsítványt, és a ta kulcsot.

./easyrsa init-pki
./easyrsa gen-dh
./easyrsa build-ca nopass
./easyrsa build-server-full SERVER_NAME nopass
openvpn --genkey --secret ta.key

Aztán jöhetnek is a kliensek.

./easyrsa build-client-full CLIENT_NAME nopass

A konfigokat a saját fejlesztésű szkriptünkkel hozzuk létre.

/usr/bin/dlt_genovpn -a server -n servername
/usr/bin/dlt_genovpn -a client -n clientname -r server_hostname



Shell script varázslat: find és xargs

dark Dokumentáció 2021-12-07 11:43:00

Find és xargs.


Üres könytárak törlése

find ./ -type d -empty -print0 | xargs -0 -I {} rmdir -v "{}"

-print0 -0 : A szpészek és sortörések okozta problémák kiküszöbölésére szolgál.

-I {} : Az xargs által átvett argumentumokat helyettesíti be a meghívott parancs argumentum listájába. Nézhetne ki úgy is, hogy xargs -0 -I dir rmdir -v "dir" .


PowerDNS telepítés

dark Dokumentáció 2021-12-06 20:20:00

A jó öreg Bind névszerver évtizedeken keresztül jól bevált. Basszunk ki magunkkal és vezessünk be helyette valami újat!


Szükséges csomagok

apt install pdns-server pdns-recursor pdns-backend-mysql dnsdist

Konfiguráció

Az authoritatív

Ez az a rész, ami az illetékességhez kell. Azaz, ha az enyém a morknat.hu domain, akkor kell nekem egy authoritatív elsődleges és másodlagos dns szerver.

/etc/powerdns/pdns.conf

api=yes
api-key=apitapi
include-dir=/etc/powerdns/pdns.d
launch=
local-address=127.0.0.1
local-port=5300
master=yes
security-poll-suffix=
setgid=pdns
setuid=pdns
slave=yes
webserver=yes
webserver-address=0.0.0.0
webserver-allow-from=0.0.0.0/0,::/0
webserver-port=8081

/etc/powerdns/pdns.d/gmysql.conf

Igen, olyat tud, hogy MySQL-ben tárolja a zónák adatait.

launch+=gmysql
gmysql-host=localhost
gmysql-port=3306
gmysql-dbname=powerdns
gmysql-user=powerdns
gmysql-password=jóamatőrlennehaidemásoltamvolna
gmysql-dnssec=yes

A rekurzor

/etc/powerdns/recursor.conf

Nem úgy, mint a Bind-nél, ez itt egy külön mutatvány. Enélkül a Powerdns nem fog névfeloldást produkálni sem a localhost, sem a helyi hálózat számára.

forward-zones=example.com=127.0.0.1:5300
hint-file=/usr/share/dns/root.hints
include-dir=/etc/powerdns/recursor.d
local-address=127.0.0.1
local-port=5301
lua-config-file=/etc/powerdns/recursor.lua
quiet=yes
security-poll-suffix=
setgid=pdns
setuid=pdns

MySQL

CREATE DATABASE IF NOT EXISTS `powerdns` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE OR REPLACE USER 'powerdns'@'%' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON `powerdns`.* TO 'powerdns'@'%';
FLUSH PRIVILEGES;
mysql -u root -p powerdns

Dnsdist

Csak, hogy ne legyen már olyan egyszerű. Az authoritatív és a rekurzor szerverek a localhost-on tanyáznak és még csak nem is a szokásos UDP 53-as porton. A külvilág számára a dnsdist lesz látható, ami eldönti, hogy a beérkező kéréseket melyik szervernek érdemes továbbítani.

/etc/dnsdist/dnsdist.conf

setSecurityPollSuffix("")

setLocal('127.0.0.1:53')
addLocal('192.168.12.3:53')
setACL({'0.0.0.0/0', '::/0'})

newServer({address='127.0.0.1:5300', pool='auth'})
newServer({address='127.0.0.1:5301', pool='recursor'})

recursive_ips = newNMG()
recursive_ips:addMask('127.0.0.0/8')
recursive_ips:addMask('192.168.12.0/24')

addAction(NetmaskGroupRule(recursive_ips), PoolAction('recursor'))
addAction(AllRule(), PoolAction('auth'))

PowerDns-Admin

Webes felület.

2021. december 06. hétfő

docker-compose.yml

version: '3'
services:
  powerdns-admin:
    image: ngoduykhanh/powerdns-admin:latest
    network_mode: bridge
    ports:
      - 192.168.12.3:9191:80
    extra_hosts:
      - docker:172.17.42.1
    volumes:
      - ./volumes/data:/data
    environment:
      - SECRET_KEY=összevisszakarakterek
    restart: always


Vim modulok

Helyesebben: Neovim modulok

dark Dokumentáció 2021-11-17 12:13:00


Nem kevés időm megy el rendszeresen azzal, hogy átnézem, milyen modulokat telepítettem a fejlesztői környezetembe, aztán gondolkodom majdnem minden másodiknál, hogy ezt vajon miért? Most a sokadik átnézés és gyomlálás után dokumentálok végre.

2021. november 17. szerda

A modulok

ale - Asynchronous Lint Engine

Kódformázás - arra való. Megnyomom az F11 -et, lefut az : ALEFix , megformázódik a kód.

let g:ale_fixers = {
\   '*': ['remove_trailing_lines', 'trim_whitespace'],
\   'cpp': ['clang-format'],
\   'htmldjango': ['prettier'],
\   'javascript': ['eslint'],
\   'php': ['php_cs_fixer'],
\   'python': ['yapf']
\}

Hinting, azaz ellenőrzés nincs, azt a Coc csinálja.

coc.nvim - Conquer of Completion

Kódkiegészítés. Többek között.

Nodejs extension host for vim & neovim, load extensions like VSCode and host language servers.

Kiterjesztései is vannak, amiket már a : CocInstall paranccsal lehet telepíteni.

  • coc-yank : a legutóbb másolt kódrészletek listája, azaz : CocList -A --normal yank . F8 .
  • coc-vimlsp : Vim kódkiegészítés.
  • coc-tabnine : Gépi tanulós kódkiegészítő.
  • coc-snippets : Kódrészlet, azaz snippet kiegészítő. Önmagában nem csinál semmit, kell neki a vim-snippets .
  • coc-phpls : PHP kódkiegészítés.
  • coc-pairs : Automatikus zárójel bezáró.
  • coc-html : Html kódkiegészítés.
  • coc-diagnostics : Ez csinálja a kódellenőrzést, amit az ALE nem. leader , F7 .
  • coc-python : Python kódkiegészítés.
  • coc-css : CSS kódkiegészítés.
  • coc-clangd : C, C++ kódkiegészítés.

ctrlsf.vim

Pont ez az egyik, amiről sose tudom, hogy miért is van.

Aszinkron kódkereső. Tömeges fájlszerkesztésre is használható. Használni ugyan nem szoktam, de egyelőre nem távolítom el, mert olyan jónak tűnik (gondolom ezért úszta meg az előző gyomlálásokat is).

far.vim

Kereső-cserélő eszköz. Használni nem szoktam, pedig olyan jónak tűnik. Lsd: ctrlsf.vim .

fzf.vim

A név magáért beszél: fzf. A : Buffers F5 , : Files F6 és : Lines F7 listái nélkülözhetetlenek.

nerdcommenter

Okos forráskód ki-bekommentelő. tab , k .

rnvimr

A legújabb szerzemény, a Nerdtree-t váltotta le - Ranger fájlkezelő integráció. Nélkülözhetetlen.

2021. november 17. szerda

tabular

Tetszőleges szövegből készít szépen igazított táblázatot tetszőleges elválasztó karakter megadásával. tab , t .

tagbar

Oldalsáv, benne az aktuális forráskód fájl szerkezetével. Navigálható, nyitható, csukható. F9 .

vim-airline

Státuszsor a Vim ablakok aljára. Olyan dolog, amit az ember szándékosan sosem nézeget, de ha nem lenne, nagyon hiányozna.

vim-doge

Gombnyomásra létrehozza PHP, Python, stb. függvények és osztályok szépen formázott dokumentációját. tab , g .

vim-fugitive

Git integráció. Néhány gombnyomással lehet diff-et nézni, add-olni, commit-olni, push-olni. A : Gdiffsplit -től eltekintve nem sok haszna van, mert a git-tel kapcsolatos feladatok többségét kényelmesebb parancssorból intézni.

vim-grepper

Aszinkron kereső, ami a ripgrep eszközön alapul.

vim-polyglot

Pompás kis nyelvi csomag szintakszis kiemeléshez. Még az nginx konfig fájljait is ismeri. Egyébként meg: ansible, csv, docker, json, markdown, stb.

vim-rooter

Fájl megnyitásakor a projekt gyökérkönyvtárába lép, amit úgy talál meg, hogy a könyvtárstruktúrában felfelé haladva .git könyvtárat keres.

vim-signify

A baloldali signcolumn sorban jelzi, hogy a szerkesztett fájl mely sorai térnek el a verziókövetőben tárolt változatuktól.

vim-snippets

Előre definiált kódrészletek kódkiegészítéshez. Jól jöhet, ha az adott nyelven nem tudjuk éppen, hogyan kell try/except-et, vagy for ciklust írni. Ez kell a fentebb említett coc-snippets -nek.

vim-startify

Ascii art tehén és legutóbb megnyitott fájlok listája a vim kezdőképernyőjén, vagy leader , s . Enélkül élni nem lehet.

vim-tmux-navigator

Akadálymentes közlekedést biztosít Tmux és Vim ablakok között.


Shell script varázslat

dark Dokumentáció 2021-11-11 19:44:00

Amikor az kell, hogy az aktuális könyvtár a szkript saját könyvtára legyen.


Az egyszerű megoldás

#!/bin/sh

cd "$(dirname $0)"

A komolyabb

Hogy a könyvtár váltás kövesse a szimbolikus linkeket.

#!/usr/bin/env bash

SCRIPTDIR="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")"
cd "${SCRIPTDIR}" || exit 1

A GOG-nál így csinálják

A játékok start.sh szkriptjének első sorai.

#!/usr/bin/env bash

CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd "${CURRENT_DIR}"

A legszebb megoldás Bash nélkül

#!/usr/bin/env sh

cd "$(dirname "$(readlink -f "$0")")" || exit

Headless Firefox futtatása Pythonból Seleniummal

dark Dokumentáció 2021-01-15 11:22:00

Ezt csináljuk akkor, mikor nem elég a wgettel letöltött html forrás, mert kell a javascriptes, iframe-es tartalom is.


Szerezzük meg például megadott weboldal Facebook megosztásainak, vagy számát rendkívül elegáns módon.

Előkészület

Létrehozunk egy Python venvet és telepítjük a selenium nevű csomagot. Letöltjük a mozilla geckodriver t és telepítjük a Firefox ot, ha még nem tettük volna. Grafikus felületre nem lesz szükség.

Aztán

#!/usr/bin/env venv/bin/python
import os
import sys

from selenium.webdriver import Firefox
from selenium.webdriver.common.by import By
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.firefox.webelement import FirefoxWebElement
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.ui import WebDriverWait

options: Options = Options()
options.headless = True
executable_path = os.path.join(os.path.dirname(__file__), 'geckodriver')
url: str = sys.argv[1]

driver: Firefox = Firefox(options=options, executable_path=executable_path)
driver.get(url)
fbframe: FirefoxWebElement = WebDriverWait(driver, 10).until(
    expected_conditions.presence_of_element_located(
        (By.XPATH, '//iframe[starts-with(@data-testid, "fb:like")]')))
driver.switch_to.frame(fbframe)
span: FirefoxWebElement = WebDriverWait(driver, 10).until(
    expected_conditions.presence_of_element_located((By.ID, 'u_0_3')))
print(span.text)

driver.close()
driver.quit()

Megjegyzés

A szkriptet futtató felhasználónak kell, hogy legyen írási joga a home könyvtárára - ugye a www-data usernek nem szokott lenni - ennélkül nem fog működni. A home könyvtárban jön létre a .cache és a Firefox profilt tartalmazó .mozilla alkönyvtár.


Windows parancsok

dark Dokumentáció 2020-12-28 17:11:00

Dolgok, amiket akkor se fogok megjegyezni. Mert ha fejben tartanék mindent, amire x évenként van szükség, lehet, hogy az alapvető biológiai funkcióim szabályozását felejteném el.


Driver telepítése úgynevezett parancssorból

A Windows, az úgynevezett operációs rendszer úgynevezett parancssoráról van szó.

pnputil -a viostor.inf

Hibernálás letiltása

Hogy ne pazaroljunk még több lemezterületet az úgynevezett operációs rendszer miatt.

powercfg.exe -h off
mklink /D c:\Games d:\Games

Samba megosztás csatolása

Mert még a Windows alapú játékokat is Linuxon tároljuk.

net use z: \\server\share /user:username password

Particionáló cucc

diskpart

Hálózati beállítások

ipconfig

Server 2019

Total commender nélkül szart se ér az egész

Így történik a letöltés.

Invoke-WebRequest -UseBasicParsing -Uri https://totalcommander.ch/win/tcmd950x64.exe -OutFile c:\tc.exe

Dolgok, amik még hiányoznának

# Server Core App Compatibility Feature on Demand
# https://docs.microsoft.com/en-us/windows-server/get-started-19/install-fod-19
Add-WindowsCapability -Online -Name ServerCore.AppCompatibility~~~~0.0.1.0

OpenSSH telepítés

# Install the OpenSSH Client
Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0

# Install the OpenSSH Server
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
Start-Service sshd

# OPTIONAL but recommended:
Set-Service -Name sshd -StartupType 'Automatic'
# Confirm the Firewall rule is configured. It should be created automatically by setup.
Get-NetFirewallRule -Name *ssh*
# There should be a firewall rule named "OpenSSH-Server-In-TCP", which should be enabled
# If the firewall does not exist, create one
New-NetFirewallRule -Name sshd -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22


Egy médiafigyelési feladatokat végrehajtó Python szkript vázlata

dark Dokumentáció 2020-12-08 20:25:00

Nevezhetjük úgy is, hogy rss letöltő és feldolgozó és html letöltő és feldolgozó.


A feledat lényege, hogy ismétlődő jelleggel letöltjük egy weboldal rss-ét, utána végighaladunk az egyes elemeken, letöltjük a linkelt html-t, abból pedig adatokat nyerünk ki és tárolunk. Így kell nekiállni:

Függőségek

RSS értelmező

pip install feedparser

HTML feldolgozó

pip install BeautifulSoup

A szkript

import datetime
import re
import sys

import bs4
import feedparser
import requests

feed: feedparser.FeedParserDict = feedparser.parse(sys.argv[1])

for entry in feed["entries"]:
    link: str = entry.link
    guid: str = entry.guid
    title: str = entry.title
    lead: str = entry.description
    published: datetime.datetime = datetime.datetime(
        *(entry.published_parsed[:6]))

    response: requests.Response = requests.get(link)
    soup: bs4.BeautifulSoup = bs4.BeautifulSoup(
        response.content.decode("utf-8", errors="ignore"), "html.parser")
    article_tag: bs4.element.Tag = soup.find(
           "div", attrs={"class": "content"})
    html_cleanup(article_tag)
    article_text: str = prettify(article_tag)
    article_author: str = soup.find("div", attrs={
        "class": "info"
    }).find("a").text

A segédfüggvények, amik kitakarítják a HTML-t, csak azokat a tag-eket és attribútumokat meghagyva, amik minimálisan szükségesek ahhoz, hogy a tartalom olvasható legyen.

def html_cleanup(tag: bs4.element.Tag) -> None:
    """
    Kitakarítja a html kódot

    A tag értéket ugye referenciaként vette át, úgyhogy visszatérési érték
    nem kell.
    """
    children = list(tag.recursiveChildGenerator())

    for child in children:
        try:
            if (not child):
                continue
            # kommentek törlése
            if (isinstance(child, bs4.element.Comment)):
                child.replaceWith("")
                continue
            # a sima szöveg elemeket békén hagyjuk
            if (isinstance(child, bs4.element.NavigableString)):
                continue

            # attribútumok törlése, kivéve href és src
            for k in list(child.attrs.keys()):
                if (k not in ("href", "src")):
                    del child[k]

            # javascript és css törlése
            if (child.name in ("style", "script")):
                child.decompose()
            # bizonyos tag-ek maradhatnak
            elif (child.name in ("a", "em", "p", "h1", "h2", "h3", "h4", "h5",
                                 "h6", "strong", "table", "td", "tr")):
                pass
            # képek átalakítása a képre mutató linkekre
            elif child.name == "img":
                child.replaceWith(
                    bs4.BeautifulSoup(
                        "{0}".format(child['src']),
                        "html.parser"))
            # minden további html tag eltávolítása
            else:
                child.unwrap()
        except Exception as e:
            print("Error", e)

def prettify(tag: bs4.element.Tag) -> str:
    """
    Szépen formázott html string
    """
    soup = bs4.BeautifulSoup("{}".format(tag.decode_contents()),
                             "html.parser")
    return (soup.prettify())

A legújabb, 3.9-es Python és a 5.2.1-es verziószámú feedparser nem biztos, hogy jóban lesznek egymással

Traceback (most recent call last):
  File "/tmp/tmp.py", line 6, in
    import feedparser
  File "/home/dark/morkpy_venv/lib/python3.9/site-packages/feedparser.py", line 93, in
    _base64decode = getattr(base64, 'decodebytes', base64.decodestring)
AttributeError: module 'base64' has no attribute 'decodestring'

Az ideiglenes megoldás:

import base64

base64.decodestring = base64.decodebytes


MySQL adatbázisból CSV fájlba Pythonban

dark Dokumentáció 2020-12-02 08:57:00


Előfordul, hogy adatázisból kell kimutatást készíteni, amit Excelben nézegethetnek, vagy éppen adatokat kell átvarázsolni MySQL-ből egy CSV formátumot váró rendszerbe. Nem bonyolult, de legutóbb megint keresgélnem kellett, hogy milyen API-n keresztül és hogyan lehet Pythonban lekérdezéseket végrehajtani, illetve, hogyan kell a csv writer-t paraméterezni, ezért most vázlatosan idedokumentálom, hogy legközelebb ne kelljen sokat gondolkozni, hogy hol keressem.

venv/bin/pip install mysqlclient
#!/usr/bin/env venv/bin/python3
import csv
import re
import sys

import MySQLdb

def main(db_host: str, db_db: str, db_user: str, db_passwd: str, outfile: str):
    db = MySQLdb.connect(host=db_host,
                         db=db_db,
                         user=db_user,
                         passwd=db_passwd,
                         charset='utf8')
    cursor = db.cursor(MySQLdb.cursors.DictCursor)

    cursor.execute("""\
        SELECT * FROM `user`
        JOIN `group` ON user_group_id = group.group_id
        WHERE user_created
        ORDER BY user_created DESC""")

    with open(outfile, "w") as csvfile:
        csvwriter = csv.writer(csvfile, delimiter=",")
        csvwriter.writerow(
            ("EMAIL", "FIRSTNAME", "PHONE", "CREATION_DATE", "GENDER"))

        for line in cursor.fetchall():
            email: str = line['user_email']
            firstname: str = line['group_desc']
            phone: str = ""
            creation: str = str(
                line['user_created'])[0:10]if line['user_created']else ""
            gender: str = str(line['user_gender']) or "0"

            csvwriter.writerow((email, firstname, phone, creation, gender))

    cursor.close()

if __name__ == "__main__":
    sys.exit(main(*sys.argv[1:]))

Elfelejtett MySQL root jelszó módosítása

dark Dokumentáció 2020-12-01 14:09:00


Leállítjuk a MySQL szervert

Elindítjuk a --skip-grant-tables paraméterrel, aminek hatására localhostról jelszó nélkül tudunk csatlakozni.

mysqld_safe --skip-grant-tables &

Módosítjuk a root jelszót.

UPDATE mysql.user SET Password=PASSWORD('ujjelszo') WHERE User='root';
FLUSH PRIVILEGES;

CTRL + C

Újraindítjuk a MySQL szervert.

Örülünk.


Debian 10 - phpMyAdmin

dark Dokumentáció 2020-12-01 10:10:00


Debian 10-re való frissítéskor észrevehetjük, hogy a phpMyAdmin csomag obsolete lett, azaz hivatalos tárolóból már nem telepíthető. Nem nagy baj, többnyire eddig is kerültük az apt install webescuccrengetegfüggőséggelésésdisztribúcióspecifikuskonfigurációval típusú megoldásokat, de ha esetleg van még ilyenünk, akkor ideje eltakarítani és beüzemelni egy jobb megoldást.

Először tehát takarítunk

apt --purge remove phpmyadmin
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages were automatically installed and are no longer required:
  dbconfig-common dbconfig-mysql libjs-sphinxdoc libjs-underscore php-bz2 php-curl php-gd php-mysql php-php-gettext php-phpseclib php7.3-bz2 php7.3-curl php7.3-gd php7.3-mysql
Use 'apt autoremove' to remove them.
The following packages will be REMOVED:
  phpmyadmin*
0 upgraded, 0 newly installed, 1 to remove and 0 not upgraded.
After this operation, 24.8 MB disk space will be freed.
Do you want to continue? [Y/n]y
(Reading database ... 55135 files and directories currently installed.)
Removing phpmyadmin (4:4.6.6-4+deb9u2) ...
Determining localhost credentials from /etc/mysql/debian.cnf: succeeded.

A felmerülő kérdésekre igent mondunk, azaz:

Deconfigure database for phpmyadmin with dbconfig-common?

Yes.

Delete the database for phpmyadmin?

Yes.

dbconfig-common: dumping mysql database phpmyadmin to /var/tmp/phpmyadmin.phpmyadmin.2020-12-01-10.08.mysql.5w9c3U.
dbconfig-common: dropping mysql database phpmyadmin.
dropping database phpmyadmin: success.
verifying database phpmyadmin was dropped: success.
dbconfig-common: revoking privileges for user phpmyadmin on phpmyadmin.
revoking access to database phpmyadmin from phpmyadmin@localhost: success.
Processing triggers for man-db (2.8.5-2) ...
(Reading database ... 53470 files and directories currently installed.)
Purging configuration files for phpmyadmin (4:4.6.6-4+deb9u2) ...

Jobb megoldás 1 - Adminer

Egyetlen PHP fájlból álló MySQL adminisztrációs felület, amit bemásolhatunk bármely PHP projektünkbe.

https://www.adminer.org/

Jobb megoldás 2 - Docker

docker-compose.yml

version: '3'
services:
  phpmyadmin:
    image: phpmyadmin
    container_name: phpmyadmin
    network_mode: bridge
    environment:
      - PMA_HOSTS=172.17.0.1
    restart: always
    ports:
      - 127.0.0.1:81:80

Megjegyzések

A PMA_HOSTS (vesszővel tagolt lista) környezeti változóval adhatjuk meg a MySQL szervek ip címeit, vagy hosztneveit.

Indítás az yml fájlt tartalmazó könyvtárból

docker-compose up -d

Nginx vhost

server {
    listen 80;
    server_name phpmyadmin.domain.hu;

    location / {
        proxy_pass http://127.0.0.1:81;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

MySQL konfiguráció

/etc/mysql/mariadb.conf.d/50-server.cnf

A MySQL szerver figyeljen az összes interface-en.

[server]
bind-address = 0.0.0.0

És még

mysql -h localhost -u root -p
SHOW GRANTS FOR 'root'@'localhost';
+--------------------------------------------------------------------------------------------------------------------------------------------------+
| Grants for root@localhost                                                                                                                        |
+--------------------------------------------------------------------------------------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO `root`@`localhost` IDENTIFIED VIA unix_socket USING '*...' WITH GRANT OPTION |
| GRANT PROXY ON ''@'%' TO 'root'@'localhost' WITH GRANT OPTION                                                                                    |
+--------------------------------------------------------------------------------------------------------------------------------------------------+
2 rows in set (0.000 sec)
SHOW GRANTS FOR 'root'@'%';
ERROR 1141 (42000): There is no such grant defined for user 'root' on host '%'
UPDATE mysql.user SET Host='%' WHERE Host='localhost';
UPDATE mysql.user SET plugin='mysql_native_password';
FLUSH PRIVILEGES;
SHOW GRANTS FOR 'root'@'%';
+--------------------------------------------------------------------------------------------------------------------------------+
| Grants for root@%                                                                                                              |
+--------------------------------------------------------------------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO `root`@`%` IDENTIFIED BY PASSWORD '*...' WITH GRANT OPTION |
+--------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.001 sec)

Működik


Vlmcsd KMS server

dark Dokumentáció 2020-11-27 14:22:00

Azaz nyílt forrású Windows (meg egyébb Microsoft termék) aktiváló szerver üzembe helyezése helyi hálózaton


Telepítés és indítás

docker-compose.yml

version: '2'
services:
  vlmcsd:
    image: 'mikolatero/vlmcsd:latest'
    network_mode: bridge
    ports:
      - '1688:1688'
docker-compose up -d

A Windows beállítása

Megmondjuk a Windows-nak, hogy mostantól a server hosztnévvel, vagy ip címmel érheti el a KMS szervert. Természetesen adminisztrátorként, parancssorból.

slmgr /skms server

Megadjuk a termékkulcsot. Windows 10 Professional esetén például:

slmgr /ipk W269N-WFGWX-YVC9B-4J6C9-T83GX

Végül elvégezzük az aktiválást.

slmgr /ato
slmgr /dli

Nextcloud telepítése

dark Dokumentáció 2020-11-25 20:12:00

A Moodle telepítés leírásából kimaradtak a Nextcloud docker image beállításának egyes részletei. Szándékosan, mivel Nextcloud-ot máshol, más okból is használunk, ezért a leírásának külön dokumentumban a helye.


Telepítés

Ugyanúgy docker-compose-t használunk.

docker-compose.yml

version: '2'
services:
  nextcloud:
    image: 'nextcloud:20.0.2'
    network_mode: bridge
    ports:
      - '127.0.0.1:18083:80'
    volumes:
      - ./volumes/nextcloud:/var/www/html
    extra_hosts:
      - 'docker:172.17.42.1'
    environment:
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud
      - MYSQL_PASSWORD=password
      - MYSQL_HOST=172.17.42.1
      - NEXTCLOUD_ADMIN_USER=root
      - NEXTCLOUD_ADMIN_PASSWORD=password
      - NEXTCLOUD_TRUSTED_DOMAINS=cloud.domain.hu
      - SMTP_HOST=172.17.42.1
      - SMTP_PORT=25
      - MAIL_FROM_ADDRESS=cloud@domain.hu

Megjegyzések

  • Az image értéknél fontos a pontos verzió megadása, hogy az ismételt docker-compose up hívásokkor még véletlenül se frissüljön automatikusan az image, mint ahogy a latest tag esetén tenné.
  • A network_mode: bridge szükséges, hogy a konténer a megadott ip címen elérje a docker host-on futó adatbázis szervert. Szép, ha a teljes szolgáltatás saját alhálózaton helyezkedik el, saját adatbázis szerverrel, azaz microservices, de futtasson és backup-oljon külön mysql konténert minden projekthez az, akinek ahhoz van kedve.
  • Az extra_hosts alatti elemek hostname / ip cím párok. Az így definiált hostnevek ugyanúgy használhatóak a konténerben, mintha az /etc/hosts fájlban lennének megadva.

Konténer indítása

# indítás
docker-compose up
# vagy
# indítás a háttérben
docker-compose up -d

Nginx vhost - reverse proxy

server {
    listen 80;
    listen 443 ssl;
    server_name cloud.domain.hu;

    ssl_certificate /etc/letsencrypt/live/cloud.domain.hu/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/cloud.domain.hu/privkey.pem;

    if ($scheme = http) {
        return 301 https://$host$request_uri;
    }

    include includes/letsencrypt;

    location = /.well-known/carddav {
        return 301 $scheme://$host:$server_port/remote.php/dav;
    }
    location = /.well-known/caldav {
        return 301 $scheme://$host:$server_port/remote.php/dav;
    }

    location / {
        proxy_pass http://127.0.0.1:18083;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_redirect off;
        proxy_buffering off;
        add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    }
}

Megjegyzések

  • A location = /.well-known/carddav és location = /.well-known/caldav bejegyzések teszik lehetővé, hogy carddav és caldav protokollon keresztül elérjük a konténerben futó Nextcloud címtárát és naptárát.
  • A proxy_set_header Upgrade $http_upgrade; és  proxy_set_header Connection "upgrade"; sorok a websocket kapcsolatok működéséhez szükségesek. Lsd: http://nginx.org/en/docs/http/websocket.html .
  • @TODO: Utánanézni, hogy a proxy_redirect off; és proxy_buffering off; miért kellenek.

Konfiguráció: volumes/nextcloud/config/config.php

'trusted_domains' =>
  array (
      0 => 'localhost',
      1 => 'cloud.domain.hu'
  ),
  'overwrite.cli.url' => 'https://cloud.domain.hu',
  'overwriteprotocol' => 'https',

Hogyan üzemeltem be a Moodle Course Management System-et

dark Dokumentáció 2020-11-25 08:14:00

Azaz eLearning rendszer felépítése Docker alapon Nextcloud integrációval


Telepítés

Mindenek előtt adjunk hálát a Dockernek, mert nélküle nemigen telepítenénk ilyen összetett cuccokat, inkább megírnánk magunk - mint ahogy azt még pár nappal ezelőtt is terveztük. Áldott legyen.

Miben is van a Moodle megírva? Nem mindegy? Hát ezért adunk hálát a Dockernek. Még az is lehet, hogy Ruby-ban, mint a GitLab, de az se baj.

Mondjuk ki érti, miért kell egy webalkalmazást Ruby-ban csinálni, mikor ott a jó öreg PHP, meg van már Python, ami ennek a honlapnak is az alapja, ha meg igazán durvát akarunk, programozhatjuk C++(cémegmeg)-ben is. ... Egyesek nem tudják jódolgukban micsinálnak. Jó, hogy nem mindjárt Scratch-ben, vagy Perl-ben ...

A lényegre térve

Először használtam docker-compose -t a saját feljesztésű szkriptjeim és konfigurációs fájljaim helyett. Nem esett rosszul. A docker-compose hátránya, hogy a docker-compose.yml -ből nem lehet shell parancsokat hívni. Előnye, hogy a docker összes funkciója elérhető rajta keresztül és nem kell évekkel ezelőtt írott szkripteket túrni, hogy lássuk, hogy egy adott beállítást hogyan kell megvalósítani. Elég a docker-compose dokumentációját túrni, ami talán rendesen meg van írva. Mert azok ott ráérnek arra is.

Tanulság : ne próbáljunk meg egy kész eszközt saját megoldásokkal kiváltani csak azért, mert nem akarjuk elolvasni a dokumentációját.

Feladat : a régi docker kezelő szkriptjeim lecserélése docker-compose-ra.

docker-compose.yml

version: '2'
services:
  nextcloud:
    image: 'nextcloud:20.0.2'
    network_mode: bridge
    ports:
      - '127.0.0.1:18083:80'
    volumes:
      - ./volumes/nextcloud:/var/www/html
    extra_hosts:
      - 'docker:172.17.42.1'
    environment:
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud
      - MYSQL_PASSWORD=password
      - MYSQL_HOST=172.17.42.1
      - NEXTCLOUD_ADMIN_USER=root
      - NEXTCLOUD_ADMIN_PASSWORD=password
      - NEXTCLOUD_TRUSTED_DOMAINS=cloud.domain.hu
      - SMTP_HOST=172.17.42.1
      - SMTP_PORT=25
      - MAIL_FROM_ADDRESS=cloud@domain.hu
  moodle:
    image: 'docker.io/bitnami/moodle:3.10.0'
    network_mode: bridge
    ports:
      - '127.0.0.1:18082:8080'
    volumes:
      - ./volumes/moodle_data:/bitnami/moodle
      - ./volumes/moodledata_data:/bitnami/moodledata
    extra_hosts:
      - 'docker:172.17.42.1'
    environment:
      - MOODLE_USERNAME=root
      - MOODLE_PASSWORD=password
      - MOODLE_EMAIL=moodle@domain.hu
      - MOODLE_SITE_NAME=moodle
      - MOODLE_DATABASE_HOST=172.17.42.1
      - MOODLE_DATABASE_PORT_NUMBER=3306
      - MOODLE_DATABASE_NAME=moodle
      - MOODLE_DATABASE_USER=moodle
      - MOODLE_DATABASE_PASSWORD=password
      - ALLOW_EMPTY_PASSWORD=yes

Megjegyzések

  • Az image értéknél fontos a pontos verzió megadása, hogy az ismételt docker-compose up hívásokkor még véletlenül se frissüljön automatikusan az image, mint ahogy a latest tag esetén tenné.
  • A network_mode: bridge szükséges, hogy a konténer a megadott ip címen elérje a docker host-on futó adatbázis szervert. Szép, ha a teljes szolgáltatás saját alhálózaton helyezkedik el, saját adatbázis szerverrel, azaz microservices, de futtasson és backup-oljon külön mysql konténert minden projekthez az, akinek ahhoz van kedve.
  • Az extra_hosts alatti elemek hostname / ip cím párok. Az így definiált hostnevek ugyanúgy használhatóak a konténerben, mintha az /etc/hosts fájlban lennének megadva.

Konténerek indítása

# indítás
docker-compose up
# vagy
# indítás a háttérben
docker-compose up -d

Nginx vhost - reverse proxy

server { 
    listen 80;
    listen 443 ssl;
    server_name moodle.domain.hu;

    ssl_certificate /etc/letsencrypt/live/moodle.domain.hu/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/moodle.domain.hu/privkey.pem;

    if ($scheme = http) {
        return 301 https://$host$request_uri;
    }

    include includes/letsencrypt;

    location / {
        proxy_pass http://127.0.0.1:18082;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
        proxy_set_header X-Real-IP $remote_addr;
        add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    }
}

Megjegyzések

A titkosítást szokás szerint a docker host-on futó nginx reverse proxy intézi, a konténerben levő Moodle meg persze, hogy nem viseli ezt olyan jól. A konfiguráció így némi módosításra szorul.

Konfiguráció: volumes/moodle_data/config.php

$CFG->wwwroot = 'https://moodle.domain.hu';
$CFG->reverseproxy = true;
$CFG->sslproxy = true;

Nextcloud integráció

HTTPS nélkül nem fog működni. Nem úgy megy az manapság, hogy webes szolgáltatásokat csinálunk külső fél, legalább a letsencrypt igénybevétele nélkül.

Nextcloud

Az Administration / Security / OAuth 2.0 clients menüpontban felveszünk egy új klienst mondjuk Moodle néven. A Redirection URI https://moodle.domain.hu/admin/oauth2callback.php lesz. Mentés után láthatóvá válik a Client Identifier és a Secret , amiket a kliens beállításánál használhatunk.

Moodle

A Site administration / Server / OAuth 2 services / Create new Nextcloud service menüpontban beállítjuk a Nextcloud OAuth 2 szolgáltatót. A Name lehet Nextcloud, a Client id és a Client secret az előző bekezdésben említett értékek. A  Service base URL a Nextcloud szolgáltatásunk címe, azaz https://cloud.domain.hu.

A következő lépés: Site administration / Plugins / Repositories / Manage repositories , ahol engedélyezzük a Nextcloud-ot, majd a Settings menüpontban létrehozunk egy repository-t.

A dolog elméletileg készen van. A felhaszálók felhasználhatnak a Nextcloudban tárolt fájlokat a Moodle tartalmainak szerkesztéséhez.


zRam - tömörített ram swap

dark Dokumentáció 2017-08-06 11:39:00

Memóriában tárolt tömörített swap eszköz létrehozása Linux-on.


Amikor nem telik egy-két nagyobb memória modulra...

Néhány egyszerű parancs

# Kernel modul betöltése
modprobe zram num_devices=2
# Tömörítési algoritmus beállítása
echo lz4 > /sys/block/zram0/comp_algorithm                                     
# Blokk eszköz méretének beállírása 4Gb-ra
echo 4G > /sys/blk/zram0/disksize    
# Blokk eszköz formázása swap-ként
mkswap /dev/zram0                      
# Prioritás beállítása. A nagyobb érték magasabb prioritást jelent.
# Lehetséges értékek: -1 - 32767
swapon -p 100 /dev/zram0

Letsencrypt

dark Dokumentáció 2017-11-07 00:00:00

Ingyenes, automatizált tanúsítvány.


Telepítés

Szükség van a certbot-auto eszközre. Ha lehet, akkor csomagkezelőből telepítve. Ha nem lehet, akkor az alábbi címről letöltve: https://certbot.eff.org

Ha az utóbbi megoldás marad, annak nem örülünk, mivel a szkript gátlástalanul telepít python csomagokat és frissítgeti magát.

Nginx beállítások

Lehetővé kell tenni, hogy a Letsencryt végrehajtsa a domainek tulajdonjogának ellenőrzését, ami annyiból áll, hogy elhelyez teszt fájlokat a megadott helyen, aztán megpróbálja elérni azokat az összes domainen, amikre a tanúsítványt kérjük.

Az alábbi sorok bekerülnek az /etc/nginx/includes/common fájlba, amit minden vhost fájl beolvas, így minden vhost alatt létezni fog a /.well-known/acme-challenge/ cím. Pl: http://www.morknat.hu/.well-known/acme-challenge/.

location ^~ /.well-known/acme-challenge/ {
     # /etc/letsencrypt/webroot/.well-known/acme-challenge/
     root /etc/letsencrypt/webroot;
}

Tanúsítványok létrehozása

A teendő annyi, mint rootként kiadni egyetlen parancsot.

certbot certonly --webroot -w /etc/letsencrypt/webroot -d morknat.hu,www.morknat.hu,mork.morknat.hu

A válasz jó esetben valami ilyesmi lesz:

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator webroot, Installer None
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for savariaforum.hu
http-01 challenge for www.savariaforum.hu
http-01 challenge for mork.savariaforum.hu
Using the webroot path /var/www/letsencrypt for all unmatched domains.
Waiting for verification...
Cleaning up challenges
Unable to clean up challenge directory /var/www/letsencrypt/.well-known/acme-challenge
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/savariaforum.hu/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/savariaforum.hu/privkey.pem
Your cert will expire on 2017-12-19. To obtain a new or tweaked
version of this certificate in the future, simply run certbot-auto
again. To non-interactively renew *all* of your certificates, run
"certbot-auto renew"
- If you like Certbot, please consider supporting our work by:
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le

Tanúsítványok megújítása

Cronból futtaható. Érdemes néha kézzel is végrehajtani, hogy kiderüljön, ha valami hiba történik. Mert ha például módosul a webszerver konfiguráció és bizonyos domainek tanúsítványai nem frissülnek, az kellemetlen lehet.

certbot renew --no-self-upgrade

Nginx vhost beállítások

A megfelelő vhost fájlok valahogy így fognak kinézni:

server {
    listen 80;
    listen 443 ssl http2;
    server_name morknat.hu;
    root /home/dark/projects/morknat.hu/;

    ssl_certificate /home/dark/Devel/ca/certs/morknat.hu.crt.pem;
    ssl_certificate_key /home/dark/Devel/ca/private/morknat.hu.key.pem;

    if ($scheme = http) {
        return 301 https://$host$request_uri;
    }

    include includes/common;
}